@ -624,7 +624,7 @@ module Prune = struct
 
			
		
	
		
			
				
					        astate 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  let  gen_prune_alias_functions  ~ prune_alias_core  comp  x  e  astate  = 
 
			
		
	
		
			
				
					  let  gen_prune_alias_functions  ~ prune_alias_core  location  integer_type_widths comp  x  e  astate  = 
 
			
		
	
		
			
				
					    (*  [val_prune_eq] is applied when the alias type is [AliasTarget.Eq].  *) 
 
			
		
	
		
			
				
					    let  val_prune_eq  = 
 
			
		
	
		
			
				
					      match  ( comp  :  Binop . t )  with 
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -655,12 +655,13 @@ module Prune = struct
 
			
		
	
		
			
				
					          assert  false 
 
			
		
	
		
			
				
					    in 
 
			
		
	
		
			
				
					    let  make_pruning_exp  =  PruningExp . make  comp  in 
 
			
		
	
		
			
				
					    prune_alias_core  ~ val_prune_eq  ~ val_prune_le  ~ make_pruning_exp  integer_type_widths  x  e  astate 
 
			
		
	
		
			
				
					    prune_alias_core  ~ val_prune_eq  ~ val_prune_le  ~ make_pruning_exp  location  integer_type_widths  x  e 
 
			
		
	
		
			
				
					      astate 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  let  prune_simple_alias  = 
 
			
		
	
		
			
				
					    let  prune_alias_core  ~ val_prune_eq  ~ val_prune_le : _  ~ make_pruning_exp  integer_type_widths  x  e 
 
			
		
	
		
			
				
					        ( { mem }  as  astate )  = 
 
			
		
	
		
			
				
					    let  prune_alias_core  ~ val_prune_eq  ~ val_prune_le : _  ~ make_pruning_exp  _ location 
 
			
		
	
		
			
				
					        integer_type_widths  x  e  ( { mem }  as  astate )  = 
 
			
		
	
		
			
				
					      List . fold  ( Mem . find_simple_alias  x  mem )  ~ init : astate  ~ f : ( fun  acc  ( lv ,  i )  -> 
 
			
		
	
		
			
				
					          let  lhs  =  Mem . find  lv  mem  in 
 
			
		
	
		
			
				
					          let  rhs  = 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -677,8 +678,8 @@ module Prune = struct
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  let  prune_size_alias  = 
 
			
		
	
		
			
				
					    let  prune_alias_core  ~ val_prune_eq  ~ val_prune_le  ~ make_pruning_exp   x  e  
 
			
		
	
		
			
				
					        ( { mem }  as  astate )  = 
 
			
		
	
		
			
				
					    let  prune_alias_core  ~ val_prune_eq  ~ val_prune_le  ~ make_pruning_exp  location  integer_type_widths
 
			
		
	
		
			
				
					        x  e  ( { mem }  as  astate )  = 
 
			
		
	
		
			
				
					      List . fold  ( Mem . find_size_alias  x  mem )  ~ init : astate 
 
			
		
	
		
			
				
					        ~ f : ( fun  astate  ( alias_typ ,  lv ,  i ,  java_tmp )  -> 
 
			
		
	
		
			
				
					          let  array_v  =  Mem . find  lv  mem  in 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -693,9 +694,7 @@ module Prune = struct
 
			
		
	
		
			
				
					            let  prune_target  val_prune  astate  = 
 
			
		
	
		
			
				
					              let  lhs'  =  val_prune  lhs  rhs  in 
 
			
		
	
		
			
				
					              let  array_v'  = 
 
			
		
	
		
			
				
					                Val . set_array_length  Location . dummy 
 
			
		
	
		
			
				
					                  ~ length : ( Val . minus_a  lhs'  ( Val . of_int_lit  i ) ) 
 
			
		
	
		
			
				
					                  array_v 
 
			
		
	
		
			
				
					                Val . set_array_length  location  ~ length : ( Val . minus_a  lhs'  ( Val . of_int_lit  i ) )  array_v 
 
			
		
	
		
			
				
					              in 
 
			
		
	
		
			
				
					              let  pruning_exp  =  make_pruning_exp  ~ lhs : lhs'  ~ rhs  in 
 
			
		
	
		
			
				
					              ( update_mem_in_prune  lv  array_v'  ~ pruning_exp  astate ,  lhs' ,  pruning_exp ) 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -718,17 +717,17 @@ module Prune = struct
 
			
		
	
		
			
				
					    gen_prune_alias_functions  ~ prune_alias_core 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  let  rec  prune_binop_left  :  . IntegerWidths . t  ->  Exp . t  ->  t  ->  t  = 
 
			
		
	
		
			
				
					   fun  e  astate  -> 
 
			
		
	
		
			
				
					  let  rec  prune_binop_left  :  Location. t  ->   Typ. IntegerWidths . t  ->  Exp . t  ->  t  ->  t  = 
 
			
		
	
		
			
				
					   fun  location  integer_type_widths e  astate  -> 
 
			
		
	
		
			
				
					    match  e  with 
 
			
		
	
		
			
				
					    |  Exp . BinOp  ( comp ,  Exp . Cast  ( _ ,  e1 ) ,  e2 )  -> 
 
			
		
	
		
			
				
					        prune_binop_left  ( Exp . BinOp  ( comp ,  e1 ,  e2 ) )  astate 
 
			
		
	
		
			
				
					        prune_binop_left  location  integer_type_widths ( Exp . BinOp  ( comp ,  e1 ,  e2 ) )  astate 
 
			
		
	
		
			
				
					    |  Exp . BinOp 
 
			
		
	
		
			
				
					        ( ( ( Binop . Lt  |  Binop . Gt  |  Binop . Le  |  Binop . Ge  |  Binop . Eq  |  Binop . Ne )  as  comp ) ,  Exp . Var  x ,  e' ) 
 
			
		
	
		
			
				
					      -> 
 
			
		
	
		
			
				
					        astate 
 
			
		
	
		
			
				
					        | >  prune_simple_alias  comp  x  e' 
 
			
		
	
		
			
				
					        | >  prune_size_alias  comp  x  e' 
 
			
		
	
		
			
				
					        | >  prune_simple_alias  location  integer_type_widths comp  x  e' 
 
			
		
	
		
			
				
					        | >  prune_size_alias  location  integer_type_widths comp  x  e' 
 
			
		
	
		
			
				
					    |  Exp . BinOp 
 
			
		
	
		
			
				
					        (  ( ( Binop . Lt  |  Binop . Gt  |  Binop . Le  |  Binop . Ge  |  Binop . Eq  |  Binop . Ne )  as  comp ) 
 
			
		
	
		
			
				
					        ,  Exp . BinOp  ( Binop . PlusA  t ,  e1 ,  e2 ) 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -737,29 +736,29 @@ module Prune = struct
 
			
		
	
		
			
				
					           Be  careful  when  you  take  into  account  integer  overflows  in  the  abstract  semantics  [ eval ] 
 
			
		
	
		
			
				
					           in  the  future .  * ) 
 
			
		
	
		
			
				
					        astate 
 
			
		
	
		
			
				
					        | >  prune_binop_left  
 
			
		
	
		
			
				
					        | >  prune_binop_left  location  integer_type_widths
 
			
		
	
		
			
				
					             ( Exp . BinOp  ( comp ,  e1 ,  Exp . BinOp  ( Binop . MinusA  t ,  e3 ,  e2 ) ) ) 
 
			
		
	
		
			
				
					        | >  prune_binop_left  
 
			
		
	
		
			
				
					        | >  prune_binop_left  location  integer_type_widths
 
			
		
	
		
			
				
					             ( Exp . BinOp  ( comp ,  e2 ,  Exp . BinOp  ( Binop . MinusA  t ,  e3 ,  e1 ) ) ) 
 
			
		
	
		
			
				
					    |  Exp . BinOp 
 
			
		
	
		
			
				
					        (  ( ( Binop . Lt  |  Binop . Gt  |  Binop . Le  |  Binop . Ge  |  Binop . Eq  |  Binop . Ne )  as  comp ) 
 
			
		
	
		
			
				
					        ,  Exp . BinOp  ( Binop . MinusA  t ,  e1 ,  e2 ) 
 
			
		
	
		
			
				
					        ,  e3  )  -> 
 
			
		
	
		
			
				
					        astate 
 
			
		
	
		
			
				
					        | >  prune_binop_left  
 
			
		
	
		
			
				
					        | >  prune_binop_left  location  integer_type_widths
 
			
		
	
		
			
				
					             ( Exp . BinOp  ( comp ,  e1 ,  Exp . BinOp  ( Binop . PlusA  t ,  e3 ,  e2 ) ) ) 
 
			
		
	
		
			
				
					        | >  prune_binop_left  
 
			
		
	
		
			
				
					        | >  prune_binop_left  location  integer_type_widths
 
			
		
	
		
			
				
					             ( Exp . BinOp  ( comp_rev  comp ,  e2 ,  Exp . BinOp  ( Binop . MinusA  t ,  e1 ,  e3 ) ) ) 
 
			
		
	
		
			
				
					    |  _  -> 
 
			
		
	
		
			
				
					        astate 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  let  prune_binop_right  :  . IntegerWidths . t  ->  Exp . t  ->  t  ->  t  = 
 
			
		
	
		
			
				
					   fun  e  astate  -> 
 
			
		
	
		
			
				
					  let  prune_binop_right  :  Location. t  ->   Typ. IntegerWidths . t  ->  Exp . t  ->  t  ->  t  = 
 
			
		
	
		
			
				
					   fun  location  integer_type_widths e  astate  -> 
 
			
		
	
		
			
				
					    match  e  with 
 
			
		
	
		
			
				
					    |  Exp . BinOp  ( ( ( Binop . Lt  |  Binop . Gt  |  Binop . Le  |  Binop . Ge  |  Binop . Eq  |  Binop . Ne )  as  c ) ,  e1 ,  e2 ) 
 
			
		
	
		
			
				
					      -> 
 
			
		
	
		
			
				
					        prune_binop_left  ( Exp . BinOp  ( comp_rev  c ,  e2 ,  e1 ) )  astate 
 
			
		
	
		
			
				
					        prune_binop_left  location  integer_type_widths ( Exp . BinOp  ( comp_rev  c ,  e2 ,  e1 ) )  astate 
 
			
		
	
		
			
				
					    |  _  -> 
 
			
		
	
		
			
				
					        astate 
 
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -786,13 +785,13 @@ module Prune = struct
 
			
		
	
		
			
				
					        else  astate 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  let  rec  prune_helper  e  astate  = 
 
			
		
	
		
			
				
					  let  rec  prune_helper  location  integer_type_widths e  astate  = 
 
			
		
	
		
			
				
					    let  astate  = 
 
			
		
	
		
			
				
					      astate 
 
			
		
	
		
			
				
					      | >  prune_unreachable  integer_type_widths  e 
 
			
		
	
		
			
				
					      | >  prune_unop  e 
 
			
		
	
		
			
				
					      | >  prune_binop_left  e 
 
			
		
	
		
			
				
					      | >  prune_binop_right  e 
 
			
		
	
		
			
				
					      | >  prune_binop_left  location  integer_type_widths e 
 
			
		
	
		
			
				
					      | >  prune_binop_right  location  integer_type_widths e 
 
			
		
	
		
			
				
					    in 
 
			
		
	
		
			
				
					    let  is_const_zero  x  = 
 
			
		
	
		
			
				
					      match  Exp . ignore_integer_cast  x  with 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -803,32 +802,34 @@ module Prune = struct
 
			
		
	
		
			
				
					    in 
 
			
		
	
		
			
				
					    match  e  with 
 
			
		
	
		
			
				
					    |  Exp . BinOp  ( Binop . Ne ,  e1 ,  e2 )  when  is_const_zero  e2  -> 
 
			
		
	
		
			
				
					        prune_helper  e1  astate 
 
			
		
	
		
			
				
					        prune_helper  location  integer_type_widths e1  astate 
 
			
		
	
		
			
				
					    |  Exp . BinOp  ( Binop . Eq ,  e1 ,  e2 )  when  is_const_zero  e2  -> 
 
			
		
	
		
			
				
					        prune_helper  ( Exp . UnOp  ( Unop . LNot ,  e1 ,  None ) )  astate 
 
			
		
	
		
			
				
					        prune_helper  location  integer_type_widths ( Exp . UnOp  ( Unop . LNot ,  e1 ,  None ) )  astate 
 
			
		
	
		
			
				
					    |  Exp . UnOp  ( Unop . Neg ,  Exp . Var  x ,  _ )  -> 
 
			
		
	
		
			
				
					        prune_helper  ( Exp . Var  x )  astate 
 
			
		
	
		
			
				
					        prune_helper  location  integer_type_widths ( Exp . Var  x )  astate 
 
			
		
	
		
			
				
					    |  Exp . BinOp  ( Binop . LAnd ,  e1 ,  e2 )  -> 
 
			
		
	
		
			
				
					        astate  | >  prune_helper  integer_type_widths  e1  | >  prune_helper  integer_type_widths  e2 
 
			
		
	
		
			
				
					        astate 
 
			
		
	
		
			
				
					        | >  prune_helper  location  integer_type_widths  e1 
 
			
		
	
		
			
				
					        | >  prune_helper  location  integer_type_widths  e2 
 
			
		
	
		
			
				
					    |  Exp . UnOp  ( Unop . LNot ,  Exp . BinOp  ( Binop . LOr ,  e1 ,  e2 ) ,  t )  -> 
 
			
		
	
		
			
				
					        astate 
 
			
		
	
		
			
				
					        | >  prune_helper  ( Exp . UnOp  ( Unop . LNot ,  e1 ,  t ) ) 
 
			
		
	
		
			
				
					        | >  prune_helper  ( Exp . UnOp  ( Unop . LNot ,  e2 ,  t ) ) 
 
			
		
	
		
			
				
					        | >  prune_helper  location  integer_type_widths ( Exp . UnOp  ( Unop . LNot ,  e1 ,  t ) ) 
 
			
		
	
		
			
				
					        | >  prune_helper  location  integer_type_widths ( Exp . UnOp  ( Unop . LNot ,  e2 ,  t ) ) 
 
			
		
	
		
			
				
					    |  Exp . UnOp  ( Unop . LNot ,  Exp . BinOp  ( ( Binop . Lt  as  c ) ,  e1 ,  e2 ) ,  _ ) 
 
			
		
	
		
			
				
					    |  Exp . UnOp  ( Unop . LNot ,  Exp . BinOp  ( ( Binop . Gt  as  c ) ,  e1 ,  e2 ) ,  _ ) 
 
			
		
	
		
			
				
					    |  Exp . UnOp  ( Unop . LNot ,  Exp . BinOp  ( ( Binop . Le  as  c ) ,  e1 ,  e2 ) ,  _ ) 
 
			
		
	
		
			
				
					    |  Exp . UnOp  ( Unop . LNot ,  Exp . BinOp  ( ( Binop . Ge  as  c ) ,  e1 ,  e2 ) ,  _ ) 
 
			
		
	
		
			
				
					    |  Exp . UnOp  ( Unop . LNot ,  Exp . BinOp  ( ( Binop . Eq  as  c ) ,  e1 ,  e2 ) ,  _ ) 
 
			
		
	
		
			
				
					    |  Exp . UnOp  ( Unop . LNot ,  Exp . BinOp  ( ( Binop . Ne  as  c ) ,  e1 ,  e2 ) ,  _ )  -> 
 
			
		
	
		
			
				
					        prune_helper  ( Exp . BinOp  ( comp_not  c ,  e1 ,  e2 ) )  astate 
 
			
		
	
		
			
				
					        prune_helper  location  integer_type_widths ( Exp . BinOp  ( comp_not  c ,  e1 ,  e2 ) )  astate 
 
			
		
	
		
			
				
					    |  _  -> 
 
			
		
	
		
			
				
					        astate 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  let  prune  :  . IntegerWidths . t  ->  Exp . t  ->  Mem . t  ->  Mem . t  = 
 
			
		
	
		
			
				
					   fun  e  mem  -> 
 
			
		
	
		
			
				
					  let  prune  :  Location. t  ->   Typ. IntegerWidths . t  ->  Exp . t  ->  Mem . t  ->  Mem . t  = 
 
			
		
	
		
			
				
					   fun  location  integer_type_widths e  mem  -> 
 
			
		
	
		
			
				
					    let  mem ,  prune_pairs  =  Mem . apply_latest_prune  e  mem  in 
 
			
		
	
		
			
				
					    let  { mem ;  prune_pairs }  =  prune_helper  e  { mem ;  prune_pairs }  in 
 
			
		
	
		
			
				
					    let  { mem ;  prune_pairs }  =  prune_helper  location  integer_type_widths e  { mem ;  prune_pairs }  in 
 
			
		
	
		
			
				
					    if  PrunePairs . is_reachable  prune_pairs  then  Mem . set_prune_pairs  prune_pairs  mem 
 
			
		
	
		
			
				
					    else  Mem . unreachable 
 
			
		
	
		
			
				
					end