@ -10,35 +10,35 @@
 
			
		
	
		
		
			
				
					
					open !  IStd open !  IStd  
			
		
	
		
		
			
				
					
					module  F  =  Format module  F  =  Format  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					type  _ typ  =  Typ . t module  Raw  =  struct  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					  type  _ typ  =  Typ . t 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  compare__typ  _  _  =  0    let  compare__typ  _  _  =  0  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					(*  ignore types while comparing bases. we can't trust the types from all of our frontends to be    (*  ignore types while comparing bases. we can't trust the types from all of our frontends to be  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					   consistent ,  and  the  variable  names  should  already  be  enough  to  distinguish  the  bases .  * ) 
   consistent ,  and  the  variable  names  should  already  be  enough  to  distinguish  the  bases .  * ) 
 
			
		
	
		
		
			
				
					
					type  base  =  Var . t  *  _ typ  [ @@ deriving  compare ]    type  base  =  Var . t  *  _ typ  [ @@ deriving  compare ]  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  equal_base  =  [ % compare . equal  :  base ]    let  equal_base  =  [ % compare . equal  :  base ]  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					type  access  =  ArrayAccess  of  Typ . t  |  FieldAccess  of  Typ . Fieldname . t  [ @@ deriving  compare ]    type  access  =  ArrayAccess  of  Typ . t  |  FieldAccess  of  Typ . Fieldname . t  [ @@ deriving  compare ]  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  equal_access  =  [ % compare . equal  :  access ]    let  equal_access  =  [ % compare . equal  :  access ]  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  equal_access_list  l1  l2  =  Int . equal  ( List . compare  compare_access  l1  l2 )  0    let  equal_access_list  l1  l2  =  Int . equal  ( List . compare  compare_access  l1  l2 )  0  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  pp_base  fmt  ( pvar ,  _ )  =  Var . pp  fmt  pvar    let  pp_base  fmt  ( pvar ,  _ )  =  Var . pp  fmt  pvar  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  pp_access  fmt  =  function    let  pp_access  fmt  =  function  
			
				
				
			
		
	
		
		
			
				
					
					  |  FieldAccess  field_name 
     |  FieldAccess  field_name  
			
				
				
			
		
	
		
		
			
				
					
					   ->  Typ . Fieldname . pp  fmt  field_name 
      ->  Typ . Fieldname . pp  fmt  field_name 
 
			
				
				
			
		
	
		
		
			
				
					
					  |  ArrayAccess  _ 
     |  ArrayAccess  _  
			
				
				
			
		
	
		
		
			
				
					
					   ->  F . fprintf  fmt  " [_] " 
      ->  F . fprintf  fmt  " [_] " 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  pp_access_list  fmt  accesses  =    let  pp_access_list  fmt  accesses  =  
			
				
				
			
		
	
		
		
			
				
					
					  let  pp_sep  _  _  =  F . fprintf  fmt  " . "  in 
     let  pp_sep  _  _  =  F . fprintf  fmt  " . "  in  
			
				
				
			
		
	
		
		
			
				
					
					  F . pp_print_list  ~ pp_sep  pp_access  fmt  accesses 
     F . pp_print_list  ~ pp_sep  pp_access  fmt  accesses  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					module  Raw  =  struct  
			
		
	
		
		
			
				
					
					  type  t  =  base  *  access  list  [ @@ deriving  compare ] 
  type  t  =  base  *  access  list  [ @@ deriving  compare ] 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  equal  =  [ % compare . equal  :  t ] 
  let  equal  =  [ % compare . equal  :  t ] 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -109,6 +109,72 @@ module Raw = struct
 
			
		
	
		
		
			
				
					
					    |  _ 
    |  _ 
 
			
		
	
		
		
			
				
					
					     ->  None 
     ->  None 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  base_of_pvar  pvar  typ  =  ( Var . of_pvar  pvar ,  typ ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  base_of_id  id  typ  =  ( Var . of_id  id ,  typ ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  of_pvar  pvar  typ  =  ( base_of_pvar  pvar  typ ,  [] ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  of_id  id  typ  =  ( base_of_id  id  typ ,  [] ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  of_exp  exp0  typ0  ~ ( f_resolve_id :  Var . t  ->  t  option )  = 
 
			
		
	
		
		
			
				
					
					    (*  [typ] is the type of the last element of the access path  ( e.g., typeof ( g )  for x.f.g )   *) 
 
			
		
	
		
		
			
				
					
					    let  rec  of_exp_  exp  typ  accesses  acc  = 
 
			
		
	
		
		
			
				
					
					      match  exp  with 
 
			
		
	
		
		
			
				
					
					      |  Exp . Var  id  ->  ( 
 
			
		
	
		
		
			
				
					
					        match  f_resolve_id  ( Var . of_id  id )  with 
 
			
		
	
		
		
			
				
					
					        |  Some  ( base ,  base_accesses ) 
 
			
		
	
		
		
			
				
					
					         ->  ( base ,  base_accesses  @  accesses )  ::  acc 
 
			
		
	
		
		
			
				
					
					        |  None 
 
			
		
	
		
		
			
				
					
					         ->  ( base_of_id  id  typ ,  accesses )  ::  acc  ) 
 
			
		
	
		
		
			
				
					
					      |  Exp . Lvar  pvar  when  Pvar . is_ssa_frontend_tmp  pvar  ->  ( 
 
			
		
	
		
		
			
				
					
					        match  f_resolve_id  ( Var . of_pvar  pvar )  with 
 
			
		
	
		
		
			
				
					
					        |  Some  ( base ,  base_accesses ) 
 
			
		
	
		
		
			
				
					
					         ->  ( base ,  base_accesses  @  accesses )  ::  acc 
 
			
		
	
		
		
			
				
					
					        |  None 
 
			
		
	
		
		
			
				
					
					         ->  ( base_of_pvar  pvar  typ ,  accesses )  ::  acc  ) 
 
			
		
	
		
		
			
				
					
					      |  Exp . Lvar  pvar 
 
			
		
	
		
		
			
				
					
					       ->  ( base_of_pvar  pvar  typ ,  accesses )  ::  acc 
 
			
		
	
		
		
			
				
					
					      |  Exp . Lfield  ( root_exp ,  fld ,  root_exp_typ ) 
 
			
		
	
		
		
			
				
					
					       ->  let  field_access  =  FieldAccess  fld  in 
 
			
		
	
		
		
			
				
					
					          of_exp_  root_exp  root_exp_typ  ( field_access  ::  accesses )  acc 
 
			
		
	
		
		
			
				
					
					      |  Exp . Lindex  ( root_exp ,  _ ) 
 
			
		
	
		
		
			
				
					
					       ->  let  array_access  =  ArrayAccess  typ  in 
 
			
		
	
		
		
			
				
					
					          let  array_typ  =  Typ . mk  ( Tarray  ( typ ,  None ,  None ) )  in 
 
			
		
	
		
		
			
				
					
					          of_exp_  root_exp  array_typ  ( array_access  ::  accesses )  acc 
 
			
		
	
		
		
			
				
					
					      |  Exp . Cast  ( cast_typ ,  cast_exp ) 
 
			
		
	
		
		
			
				
					
					       ->  of_exp_  cast_exp  cast_typ  []  acc 
 
			
		
	
		
		
			
				
					
					      |  Exp . UnOp  ( _ ,  unop_exp ,  _ ) 
 
			
		
	
		
		
			
				
					
					       ->  of_exp_  unop_exp  typ  []  acc 
 
			
		
	
		
		
			
				
					
					      |  Exp . Exn  exn_exp 
 
			
		
	
		
		
			
				
					
					       ->  of_exp_  exn_exp  typ  []  acc 
 
			
		
	
		
		
			
				
					
					      |  Exp . BinOp  ( _ ,  exp1 ,  exp2 ) 
 
			
		
	
		
		
			
				
					
					       ->  of_exp_  exp1  typ  []  acc  | >  of_exp_  exp2  typ  [] 
 
			
		
	
		
		
			
				
					
					      |  Exp . Const  _  |  Closure  _  |  Sizeof  _ 
 
			
		
	
		
		
			
				
					
					       ->  (*  trying to make access path from an invalid expression  *) 
 
			
		
	
		
		
			
				
					
					          acc 
 
			
		
	
		
		
			
				
					
					    in 
 
			
		
	
		
		
			
				
					
					    of_exp_  exp0  typ0  []  [] 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  of_lhs_exp  lhs_exp  typ  ~ ( f_resolve_id :  Var . t  ->  t  option )  = 
 
			
		
	
		
		
			
				
					
					    match  of_exp  lhs_exp  typ  ~ f_resolve_id  with  [ lhs_ap ]  ->  Some  lhs_ap  |  _  ->  None 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  append  ( base ,  old_accesses )  new_accesses  =  ( base ,  old_accesses  @  new_accesses ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  rec  is_prefix_path  path1  path2  = 
 
			
		
	
		
		
			
				
					
					    if  phys_equal  path1  path2  then  true 
 
			
		
	
		
		
			
				
					
					    else 
 
			
		
	
		
		
			
				
					
					      match  ( path1 ,  path2 )  with 
 
			
		
	
		
		
			
				
					
					      |  [] ,  _ 
 
			
		
	
		
		
			
				
					
					       ->  true 
 
			
		
	
		
		
			
				
					
					      |  _ ,  [] 
 
			
		
	
		
		
			
				
					
					       ->  false 
 
			
		
	
		
		
			
				
					
					      |  access1  ::  p1 ,  access2  ::  p2 
 
			
		
	
		
		
			
				
					
					       ->  equal_access  access1  access2  &&  is_prefix_path  p1  p2 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  is_prefix  ( base1 ,  path1  as  ap1 )  ( base2 ,  path2  as  ap2 )  = 
 
			
		
	
		
		
			
				
					
					    if  phys_equal  ap1  ap2  then  true  else  equal_base  base1  base2  &&  is_prefix_path  path1  path2 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  pp  fmt  =  function 
  let  pp  fmt  =  function 
 
			
		
	
		
		
			
				
					
					    |  base ,  [] 
    |  base ,  [] 
 
			
		
	
		
		
			
				
					
					     ->  pp_base  fmt  base 
     ->  pp_base  fmt  base 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -116,112 +182,52 @@ module Raw = struct
 
			
		
	
		
		
			
				
					
					     ->  F . fprintf  fmt  " %a.%a "  pp_base  base  pp_access_list  accesses 
     ->  F . fprintf  fmt  " %a.%a "  pp_base  base  pp_access_list  accesses 
 
			
		
	
		
		
			
				
					
					end end  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					type  t  =  Abstracted  of  Raw . t  |  Exact  of  Raw . t  [ @@ deriving  compare ] module  Abs  =  struct  
			
				
				
			
		
	
		
		
			
				
					
					
  type  raw  =  Raw . t 
 
			
				
				
			
		
	
		
		
			
				
					
					let  equal  =  [ % compare . equal  :  t ] 
 
			
				
				
			
		
	
		
		
			
				
					
					
  type  t  =  Abstracted  of  Raw . t  |  Exact  of  Raw . t  [ @@ deriving  compare ] 
 
			
				
				
			
		
	
		
		
			
				
					
					let  base_of_pvar  pvar  typ  =  ( Var . of_pvar  pvar ,  typ ) 
 
			
				
				
			
		
	
		
		
			
				
					
					
  let  equal  =  [ % compare . equal  :  t ] 
 
			
				
				
			
		
	
		
		
			
				
					
					let  base_of_id  id  typ  =  ( Var . of_id  id ,  typ ) 
 
			
				
				
			
		
	
		
		
			
				
					
					
  let  extract  =  function  Exact  ap  |  Abstracted  ap  ->  ap 
 
			
				
				
			
		
	
		
		
			
				
					
					let  of_pvar  pvar  typ  =  ( base_of_pvar  pvar  typ ,  [] ) 
 
			
				
				
			
		
	
		
		
			
				
					
					
  let  with_base  base  =  function 
 
			
				
				
			
		
	
		
		
			
				
					
					let  of_id  id  typ  =  ( base_of_id  id  typ ,  [] )     |  Exact  ( _ ,  accesses ) 
 
			
				
				
			
		
	
		
		
			
				
					
					
     ->  Exact  ( base ,  accesses ) 
 
			
				
				
			
		
	
		
		
			
				
					
					let  of_exp  exp0  typ0  ~ ( f_resolve_id :  Var . t  ->  Raw . t  option )  =     |  Abstracted  ( _ ,  accesses ) 
 
			
				
				
			
		
	
		
		
			
				
					
					  (*  [typ] is the type of the last element of the access path  ( e.g., typeof ( g )  for x.f.g )   *) 
     ->  Abstracted  ( base ,  accesses ) 
 
			
				
				
			
		
	
		
		
			
				
					
					  let  rec  of_exp_  exp  typ  accesses  acc  = 
 
			
				
				
			
		
	
		
		
			
				
					
					    match  exp  with 
  let  to_footprint  formal_index  access_path  = 
 
			
				
				
			
		
	
		
		
			
				
					
					    |  Exp . Var  id  ->  ( 
    let  _ ,  base_typ  =  fst  ( extract  access_path )  in 
 
			
				
				
			
		
	
		
		
			
				
					
					      match  f_resolve_id  ( Var . of_id  id )  with 
    with_base  ( Var . of_formal_index  formal_index ,  base_typ )  access_path 
 
			
				
				
			
		
	
		
		
			
				
					
					      |  Some  ( base ,  base_accesses ) 
 
			
				
				
			
		
	
		
		
			
				
					
					       ->  ( base ,  base_accesses  @  accesses )  ::  acc 
  let  get_footprint_index  access_path  = 
 
			
				
				
			
		
	
		
		
			
				
					
					      |  None 
    let  raw_access_path  =  extract  access_path  in 
 
			
				
				
			
		
	
		
		
			
				
					
					       ->  ( base_of_id  id  typ ,  accesses )  ::  acc  ) 
    match  raw_access_path  with 
 
			
				
				
			
		
	
		
		
			
				
					
					    |  Exp . Lvar  pvar  when  Pvar . is_ssa_frontend_tmp  pvar  ->  ( 
    |  ( Var . LogicalVar  id ,  _ ) ,  _  when  Ident . is_footprint  id 
 
			
				
				
			
		
	
		
		
			
				
					
					      match  f_resolve_id  ( Var . of_pvar  pvar )  with 
     ->  Some  ( Ident . get_stamp  id ) 
 
			
				
				
			
		
	
		
		
			
				
					
					      |  Some  ( base ,  base_accesses ) 
    |  _ 
 
			
				
				
			
		
	
		
		
			
				
					
					       ->  ( base ,  base_accesses  @  accesses )  ::  acc 
     ->  None 
 
			
				
				
			
		
	
		
		
			
				
					
					      |  None 
 
			
				
				
			
		
	
		
		
			
				
					
					       ->  ( base_of_pvar  pvar  typ ,  accesses )  ::  acc  ) 
  let  is_exact  =  function  Exact  _  ->  true  |  Abstracted  _  ->  false 
 
			
				
				
			
		
	
		
		
			
				
					
					    |  Exp . Lvar  pvar 
 
			
				
				
			
		
	
		
		
			
				
					
					     ->  ( base_of_pvar  pvar  typ ,  accesses )  ::  acc 
  let  (  < =  )  ~ lhs  ~ rhs  = 
 
			
				
				
			
		
	
		
		
			
				
					
					    |  Exp . Lfield  ( root_exp ,  fld ,  root_exp_typ ) 
    match  ( lhs ,  rhs )  with 
 
			
				
				
			
		
	
		
		
			
				
					
					     ->  let  field_access  =  FieldAccess  fld  in 
    |  Abstracted  _ ,  Exact  _ 
 
			
				
				
			
		
	
		
		
			
				
					
					        of_exp_  root_exp  root_exp_typ  ( field_access  ::  accesses )  acc 
 
			
		
	
		
		
			
				
					
					    |  Exp . Lindex  ( root_exp ,  _ ) 
 
			
		
	
		
		
			
				
					
					     ->  let  array_access  =  ArrayAccess  typ  in 
 
			
		
	
		
		
			
				
					
					        let  array_typ  =  Typ . mk  ( Tarray  ( typ ,  None ,  None ) )  in 
 
			
		
	
		
		
			
				
					
					        of_exp_  root_exp  array_typ  ( array_access  ::  accesses )  acc 
 
			
		
	
		
		
			
				
					
					    |  Exp . Cast  ( cast_typ ,  cast_exp ) 
 
			
		
	
		
		
			
				
					
					     ->  of_exp_  cast_exp  cast_typ  []  acc 
 
			
		
	
		
		
			
				
					
					    |  Exp . UnOp  ( _ ,  unop_exp ,  _ ) 
 
			
		
	
		
		
			
				
					
					     ->  of_exp_  unop_exp  typ  []  acc 
 
			
		
	
		
		
			
				
					
					    |  Exp . Exn  exn_exp 
 
			
		
	
		
		
			
				
					
					     ->  of_exp_  exn_exp  typ  []  acc 
 
			
		
	
		
		
			
				
					
					    |  Exp . BinOp  ( _ ,  exp1 ,  exp2 ) 
 
			
		
	
		
		
			
				
					
					     ->  of_exp_  exp1  typ  []  acc  | >  of_exp_  exp2  typ  [] 
 
			
		
	
		
		
			
				
					
					    |  Exp . Const  _  |  Closure  _  |  Sizeof  _ 
 
			
		
	
		
		
			
				
					
					     ->  (*  trying to make access path from an invalid expression  *) 
 
			
		
	
		
		
			
				
					
					        acc 
 
			
		
	
		
		
			
				
					
					  in 
 
			
		
	
		
		
			
				
					
					  of_exp_  exp0  typ0  []  [] 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  of_lhs_exp  lhs_exp  typ  ~ ( f_resolve_id :  Var . t  ->  Raw . t  option )  =  
			
		
	
		
		
			
				
					
					  match  of_exp  lhs_exp  typ  ~ f_resolve_id  with  [ lhs_ap ]  ->  Some  lhs_ap  |  _  ->  None 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  append  ( base ,  old_accesses )  new_accesses  =  ( base ,  old_accesses  @  new_accesses )  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  with_base  base  =  function  
			
		
	
		
		
			
				
					
					  |  Exact  ( _ ,  accesses ) 
 
			
		
	
		
		
			
				
					
					   ->  Exact  ( base ,  accesses ) 
 
			
		
	
		
		
			
				
					
					  |  Abstracted  ( _ ,  accesses ) 
 
			
		
	
		
		
			
				
					
					   ->  Abstracted  ( base ,  accesses ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  rec  is_prefix_path  path1  path2  =  
			
		
	
		
		
			
				
					
					  if  phys_equal  path1  path2  then  true 
 
			
		
	
		
		
			
				
					
					  else 
 
			
		
	
		
		
			
				
					
					    match  ( path1 ,  path2 )  with 
 
			
		
	
		
		
			
				
					
					    |  [] ,  _ 
 
			
		
	
		
		
			
				
					
					     ->  true 
 
			
		
	
		
		
			
				
					
					    |  _ ,  [] 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					     ->  false 
     ->  false 
 
			
		
	
		
		
			
				
					
					    |  access1  ::  p1 ,  access2  ::  p2 
    |  Exact  lhs_ap ,  Exact  rhs_ap 
 
			
				
				
			
		
	
		
		
			
				
					
					     ->  equal_access  access1  access2  &&  is_prefix_path  p1  p2 
     ->  Raw . equal  lhs_ap  rhs_ap 
 
			
				
				
			
		
	
		
		
			
				
					
					
    |  ( Exact  lhs_ap  |  Abstracted  lhs_ap ) ,  Abstracted  rhs_ap 
 
			
				
				
			
		
	
		
		
			
				
					
					let  is_prefix  ( base1 ,  path1  as  ap1 )  ( base2 ,  path2  as  ap2 )  =      ->  Raw . is_prefix  rhs_ap  lhs_ap 
 
			
				
				
			
		
	
		
		
			
				
					
					  if  phys_equal  ap1  ap2  then  true  else  equal_base  base1  base2  &&  is_prefix_path  path1  path2 
 
			
				
				
			
		
	
		
		
			
				
					
					
  let  pp  fmt  =  function 
 
			
				
				
			
		
	
		
		
			
				
					
					let  extract  =  function  Exact  ap  |  Abstracted  ap  ->  ap     |  Exact  access_path 
 
			
				
				
			
		
	
		
		
			
				
					
					
     ->  Raw . pp  fmt  access_path 
 
			
				
				
			
		
	
		
		
			
				
					
					let  to_footprint  formal_index  access_path  =     |  Abstracted  access_path 
 
			
				
				
			
		
	
		
		
			
				
					
					  let  _ ,  base_typ  =  fst  ( extract  access_path )  in 
     ->  F . fprintf  fmt  " %a* "  Raw . pp  access_path 
 
			
				
				
			
		
	
		
		
			
				
					
					  with_base  ( Var . of_formal_index  formal_index ,  base_typ )  access_path 
end  
			
				
				
			
		
	
		
		
			
				
					
					
 
			
				
				
			
		
	
		
		
			
				
					
					let  get_footprint_index  access_path  = include  Raw  
			
				
				
			
		
	
		
		
			
				
					
					  let  raw_access_path  =  extract  access_path  in 
 
			
		
	
		
		
			
				
					
					  match  raw_access_path  with 
 
			
		
	
		
		
			
				
					
					  |  ( Var . LogicalVar  id ,  _ ) ,  _  when  Ident . is_footprint  id 
 
			
		
	
		
		
			
				
					
					   ->  Some  ( Ident . get_stamp  id ) 
 
			
		
	
		
		
			
				
					
					  |  _ 
 
			
		
	
		
		
			
				
					
					   ->  None 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  is_exact  =  function  Exact  _  ->  true  |  Abstracted  _  ->  false  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  (  < =  )  ~ lhs  ~ rhs  =  
			
		
	
		
		
			
				
					
					  match  ( lhs ,  rhs )  with 
 
			
		
	
		
		
			
				
					
					  |  Abstracted  _ ,  Exact  _ 
 
			
		
	
		
		
			
				
					
					   ->  false 
 
			
		
	
		
		
			
				
					
					  |  Exact  lhs_ap ,  Exact  rhs_ap 
 
			
		
	
		
		
			
				
					
					   ->  Raw . equal  lhs_ap  rhs_ap 
 
			
		
	
		
		
			
				
					
					  |  ( Exact  lhs_ap  |  Abstracted  lhs_ap ) ,  Abstracted  rhs_ap 
 
			
		
	
		
		
			
				
					
					   ->  is_prefix  rhs_ap  lhs_ap 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  pp  fmt  =  function  
			
		
	
		
		
			
				
					
					  |  Exact  access_path 
 
			
		
	
		
		
			
				
					
					   ->  Raw . pp  fmt  access_path 
 
			
		
	
		
		
			
				
					
					  |  Abstracted  access_path 
 
			
		
	
		
		
			
				
					
					   ->  F . fprintf  fmt  " %a* "  Raw . pp  access_path 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					module  BaseMap  =  PrettyPrintable . MakePPMap  ( struct module  BaseMap  =  PrettyPrintable . MakePPMap  ( struct  
			
		
	
		
		
			
				
					
					  type  t  =  base 
  type  t  =  base 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -239,5 +245,5 @@ module AccessMap = PrettyPrintable.MakePPMap (struct
 
			
		
	
		
		
			
				
					
					  let  pp  =  pp_access 
  let  pp  =  pp_access 
 
			
		
	
		
		
			
				
					
					end ) end )  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					module  Raw Set =  PrettyPrintable . MakePPSet  ( Raw ) module  =  PrettyPrintable . MakePPSet  ( Raw )  
			
				
				
			
		
	
		
		
			
				
					
					module  Raw Map =  PrettyPrintable . MakePPMap  ( Raw ) module  =  PrettyPrintable . MakePPMap  ( Raw )