From e8347f8c6e41ea81b634dde62d142f923931fae3 Mon Sep 17 00:00:00 2001 From: Eddy Westbrook Date: Wed, 30 Jun 2021 12:36:27 -0700 Subject: [PATCH 1/2] fixed the Heapster translation of Rust types to correctly handle return types that are enums which take up no more than 16 bytes --- heapster-saw/examples/rust_data.bc | Bin 198240 -> 196800 bytes heapster-saw/examples/rust_data.rs | 13 - heapster-saw/examples/rust_data.saw | 21 +- heapster-saw/examples/rust_data.v | 33 +++ heapster-saw/examples/rust_lifetimes.v | 7 +- .../src/Verifier/SAW/Heapster/CruUtil.hs | 16 ++ .../src/Verifier/SAW/Heapster/Permissions.hs | 51 ++++ .../src/Verifier/SAW/Heapster/RustTypes.hs | 253 +++++++++++++----- 8 files changed, 300 insertions(+), 94 deletions(-) diff --git a/heapster-saw/examples/rust_data.bc b/heapster-saw/examples/rust_data.bc index fd49d18547f39a78b1e581f174840dbde1c9006e..6cf6f5b23d202d085e2d6b23749ba5220932c3e7 100644 GIT binary patch delta 84047 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%0DEt#^O3LbIk)Vk9WllDdN1w#7&hA{ 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 z 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 { } } -/* Dummy function to figure out the size of a HashMap */ -pub fn test_hash_map_size (x:(HashMap, u64)) -> u64 { - let (_,u) = x; return u; -} - -pub fn my_hash_insert (m: &mut HashMap, x:u64, y:u64) -> Option { - return m.insert (x,y); -} - -pub fn my_hash_insert_void (m: &mut HashMap, x:u64, y:u64) -> () { - m.insert (x,y); -} - /* Insert a mapping into m from the greatest of x and y to the other */ pub fn hash_map_insert_gt_to_le (m: &mut HashMap, x:u64, y:u64) -> () { if x > y { diff --git a/heapster-saw/examples/rust_data.saw b/heapster-saw/examples/rust_data.saw index 61150aed46..87615dd329 100644 --- a/heapster-saw/examples/rust_data.saw +++ b/heapster-saw/examples/rust_data.saw @@ -50,6 +50,9 @@ heapster_define_rust_type env "pub struct MixedStruct { pub s: String, pub i1: u // TrueEnum type heapster_define_rust_type env "pub enum TrueEnum { Foo, Bar, Baz }"; +// Opaque type for Vec +//heapster_define_opaque_llvmshape env "Vec" 64 "T:llvmshape 64" "24" "\\ (T:sort 0) -> List T"; + // Opaque type for HashMap heapster_define_opaque_llvmshape env "HashMap" 64 "T:llvmshape 64, U:llvmshape 64" "56" "\\ (T:sort 0) (U:sort 0) -> List (T * U)"; @@ -79,22 +82,10 @@ heapster_assume_fun_rename env to_string_str "to_string_str" "(len:bv 64). arg0: // HashMap::insert -/* -my_hash_insert_void_sym <- heapster_find_symbol env "19my_hash_insert_void"; -heapster_assume_fun_rename env my_hash_insert_void_sym "hashmap_u64_u64_insert_void" "<'a> fn (&'a mut HashMap,u64,u64) -> ()" "\\ (l,k,v) -> Cons (k,v) l"; -*/ - -/* // FIXME: we currently pretend this always returns None -// FIXME: also, the layout is currently broken for return type of Option -my_hash_insert_sym <- heapster_find_symbol env "14my_hash_insert"; -heapster_assume_fun_rename env my_hash_insert_sym "hashmap_u64_u64_insert" "<'a> fn (&'a mut HashMap,u64,u64) -> Option" "\\ (l,k,v) -> Cons (k,v) l"; -*/ - -/* hashmap_u64_u64_insert_sym <- heapster_find_symbol env "std11collections4hash3map24HashMap$LT$K$C$V$C$S$GT$6insert"; -heapster_assume_fun_rename env hashmap_u64_u64_insert_sym "hashmap_u64_u64_insert" "<'a> fn (&'a mut HashMap,u64,u64) -> Option" "\\ (l,k,v) -> Cons (k,v) l"; -*/ +heapster_assume_fun_rename env hashmap_u64_u64_insert_sym "hashmap_u64_u64_insert" "<'a> fn (&'a mut HashMap,u64,u64) -> Option" "\\ (endl:HashMap int64Trans int64Trans * #() -> CompM (HashMap int64Trans int64Trans * #())) (h:HashMap int64Trans int64Trans) (k:int64Trans) (v:int64Trans) -> returnM ((#() -> CompM (HashMap int64Trans int64Trans * #())) * Either #() int64Trans * #()) ((\\ (_:#()) -> returnM (HashMap int64Trans int64Trans * #()) (Cons (int64Trans * int64Trans) (k,v) h, ())), Left #() int64Trans (), ())"; + /*** *** Type-Checked Functions @@ -149,7 +140,7 @@ heapster_typecheck_fun_rename env list_head_sym "list_head" "<'a> fn (l: &'a Lis // list_head_impl list_head_impl_sym <- heapster_find_symbol env "14list_head_impl"; -//heapster_typecheck_fun_rename env list_head_impl_sym "list_head_impl" "<'a> fn (l: &'a List) -> Result"; +heapster_typecheck_fun_rename env list_head_impl_sym "list_head_impl" "<'a> fn (l: &'a List) -> Result"; //heapster_typecheck_fun_rename env list_head_impl_sym "list_head_impl" "(rw:rwmodality).arg0:List),8,rw,always> -o ret:(struct(eq(llvmword(0)),exists z:bv 64. eq(llvmword(z)))) or (struct(eq(llvmword(1)),true))"; // StrStruct::new diff --git a/heapster-saw/examples/rust_data.v b/heapster-saw/examples/rust_data.v index bfc770c212..8edda650ce 100644 --- a/heapster-saw/examples/rust_data.v +++ b/heapster-saw/examples/rust_data.v @@ -57,6 +57,16 @@ Definition to_string_str : forall (e0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAW CompM (@sigT var__0 (fun (x_exsh0 : var__0) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT var__0 (fun (x_ex0 : var__0) => unit)) unit))) := fun (len : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (_1 : unit) (str : @SAWCoreVectorsAsCoqVectors.Vec (@SAWCoreVectorsAsCoqVectors.bvToNat 64 len) int8Trans) => @returnM CompM _ (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (len' : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 len' int8Trans) (prod int64Trans unit))) (@existT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (len' : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 len' int8Trans) (prod int64Trans unit)) len (pair str (pair (@mkInt64Trans len) tt))). +Definition hashmap_u64_u64_insert : forall (p0 : forall (ps : prod (@HashMap (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + let var__1 := @sigT var__0 (fun (x_ex0 : var__0) => unit) in + CompM (prod (@HashMap var__1 var__1) unit)), forall (p1 : @HashMap (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))), forall (p2 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)), forall (p3 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (forall (ps : unit), let var__1 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + let var__2 := @sigT var__1 (fun (x_ex0 : var__1) => unit) in + CompM (prod (@HashMap var__2 var__2) unit)) (prod (@SAWCorePrelude.Either unit (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) := + fun (endl : prod (@Datatypes.list (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (_1 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (_1 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)))) unit -> let var__0 := int64Trans in + CompM (prod (@HashMap var__0 var__0) unit)) (h : @Datatypes.list (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (_1 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (_1 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)))) (k : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (_1 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (v : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (_1 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) => @returnM CompM _ (prod (unit -> let var__0 := int64Trans in + CompM (prod (@HashMap var__0 var__0) unit)) (prod (@SAWCorePrelude.Either unit int64Trans) unit)) (pair (fun (_1 : unit) => @returnM CompM _ (prod (@HashMap int64Trans int64Trans) unit) (pair (@Datatypes.cons (prod int64Trans int64Trans) (pair k v) h) tt)) (pair (@SAWCorePrelude.Left unit int64Trans tt) tt)). + Definition bool_and__tuple_fun : @CompM.lrtTupleType (@CompM.LRT_Cons (@CompM.LRT_Fun (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) (fun (perm0 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) => @CompM.LRT_Fun (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) (fun (perm1 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) => @CompM.LRT_Ret (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit))))) (@CompM.LRT_Nil)) := @CompM.multiFixM (@CompM.LRT_Cons (@CompM.LRT_Fun (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) (fun (perm0 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) => @CompM.LRT_Fun (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) (fun (perm1 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) => @CompM.LRT_Ret (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit))))) (@CompM.LRT_Nil)) (fun (bool_and : @CompM.lrtToType (@CompM.LRT_Fun (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) (fun (perm0 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) => @CompM.LRT_Fun (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) (fun (perm1 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) => @CompM.LRT_Ret (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)))))) => pair (fun (p0 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) (p1 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) => @CompM.letRecM (@CompM.LRT_Nil) (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) tt (@returnM CompM _ (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)) (@existT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit) (@SAWCorePrelude.bvAnd 1 (@projT1 (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_elimEx0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit) p0) (@projT1 (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_elimEx0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit) p1)) tt))) tt). @@ -283,6 +293,29 @@ Definition list_head : @CompM.lrtToType (@CompM.LRT_Fun (forall (ps : prod (@Lis CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (prod (@SAWCorePrelude.Either (prod unit (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit)) (prod unit (prod unit unit))) unit))))) := SAWCoreScaffolding.fst list_head__tuple_fun. +Definition list_head_impl__tuple_fun : @CompM.lrtTupleType (@CompM.LRT_Cons (@CompM.LRT_Fun (forall (ps : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (fun (perm0 : forall (ps : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) => @CompM.LRT_Fun (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) (fun (perm1 : @List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) => @CompM.LRT_Ret (prod (forall (ps : unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (prod (@SAWCorePrelude.Either (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit) unit))))) (@CompM.LRT_Nil)) := + @CompM.multiFixM (@CompM.LRT_Cons (@CompM.LRT_Fun (forall (ps : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (fun (perm0 : forall (ps : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) => @CompM.LRT_Fun (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) (fun (perm1 : @List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) => @CompM.LRT_Ret (prod (forall (ps : unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (prod (@SAWCorePrelude.Either (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit) unit))))) (@CompM.LRT_Nil)) (fun (list_head_impl : @CompM.lrtToType (@CompM.LRT_Fun (forall (ps : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (fun (perm0 : forall (ps : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) => @CompM.LRT_Fun (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) (fun (perm1 : @List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) => @CompM.LRT_Ret (prod (forall (ps : unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (prod (@SAWCorePrelude.Either (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit) unit)))))) => pair (fun (p0 : forall (ps : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (p1 : @List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) => @CompM.letRecM (@CompM.LRT_Nil) (prod (forall (ps : unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (prod (@SAWCorePrelude.Either (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit) unit)) tt (@SAWCorePrelude.either (prod unit unit) (prod unit (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit))) (CompM (prod (forall (ps : unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (prod (@SAWCorePrelude.Either (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit) unit))) (fun (x_left0 : prod unit unit) => @returnM CompM _ (prod (forall (ps : unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (prod (@SAWCorePrelude.Either (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit) unit)) (pair (@SAWCorePrelude.composeM unit (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (fun (x_local0 : unit) => @returnM CompM _ (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (pair (@foldList_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (@SAWCorePrelude.Left (prod unit unit) (prod unit (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit))) (pair tt (SAWCoreScaffolding.snd x_left0)))) tt)) (@SAWCorePrelude.composeM (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) p0 (fun (x_local0 : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) => @returnM CompM _ (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (pair (SAWCoreScaffolding.fst x_local0) tt)))) (pair (@SAWCorePrelude.Right (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit tt) tt))) (fun (x_right0 : prod unit (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit))) => @returnM CompM _ (prod (forall (ps : unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (prod (@SAWCorePrelude.Either (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit) unit)) (pair (@SAWCorePrelude.composeM unit (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (fun (x_local0 : unit) => @returnM CompM _ (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (pair (@foldList_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (@SAWCorePrelude.Right (prod unit unit) (prod unit (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit))) (pair tt (pair (SAWCoreScaffolding.fst (SAWCoreScaffolding.snd x_right0)) (SAWCoreScaffolding.snd (SAWCoreScaffolding.snd x_right0)))))) tt)) (@SAWCorePrelude.composeM (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) p0 (fun (x_local0 : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) => @returnM CompM _ (prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit) (pair (SAWCoreScaffolding.fst x_local0) tt)))) (pair (@SAWCorePrelude.Left (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit (@existT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit) (@projT1 (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_elimEx0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit) (SAWCoreScaffolding.fst (SAWCoreScaffolding.snd x_right0))) tt)) tt))) (@unfoldList_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) p1))) tt). + +Definition list_head_impl : @CompM.lrtToType (@CompM.LRT_Fun (forall (ps : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (fun (perm0 : forall (ps : prod (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) => @CompM.LRT_Fun (@List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) (fun (perm1 : @List_IRT (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit))) => @CompM.LRT_Ret (prod (forall (ps : unit), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + CompM (prod (@List_IRT (@sigT var__0 (fun (x_ex0 : var__0) => unit))) unit)) (prod (@SAWCorePrelude.Either (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit) unit))))) := + SAWCoreScaffolding.fst list_head_impl__tuple_fun. + Definition str_struct_new__tuple_fun : @CompM.lrtTupleType (@CompM.LRT_Cons (@CompM.LRT_Fun (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (arg0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => @CompM.LRT_Fun unit (fun (perm0 : unit) => @CompM.LRT_Fun (@SAWCorePrelude.BVVec 64 arg0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (fun (perm1 : @SAWCorePrelude.BVVec 64 arg0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) => @CompM.LRT_Ret (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_exsh0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit))))))) (@CompM.LRT_Nil)) := @CompM.multiFixM (@CompM.LRT_Cons (@CompM.LRT_Fun (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (arg0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => @CompM.LRT_Fun unit (fun (perm0 : unit) => @CompM.LRT_Fun (@SAWCorePrelude.BVVec 64 arg0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (fun (perm1 : @SAWCorePrelude.BVVec 64 arg0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) => @CompM.LRT_Ret (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_exsh0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit))))))) (@CompM.LRT_Nil)) (fun (str_struct_new : @CompM.lrtToType (@CompM.LRT_Fun (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (arg0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => @CompM.LRT_Fun unit (fun (perm0 : unit) => @CompM.LRT_Fun (@SAWCorePrelude.BVVec 64 arg0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (fun (perm1 : @SAWCorePrelude.BVVec 64 arg0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) => @CompM.LRT_Ret (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_exsh0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit)))))))) => pair (fun (e0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (p0 : unit) (p1 : @SAWCorePrelude.BVVec 64 e0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) => @CompM.letRecM (@CompM.LRT_Nil) (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_exsh0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit))) tt (@bindM CompM _ (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_exsh0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit))) (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_exsh0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit))) (@to_string_str e0 tt p1) (fun (call_ret_val : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_exsh0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit))) => @bindM CompM _ (prod unit (prod unit unit)) (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_exsh0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit))) (@llvm__x2ememcpy__x2ep0i8__x2ep0i8__x2ei64 unit (intToBv 64 0x18%Z) p0 tt) (fun (call_ret_val1 : prod unit (prod unit unit)) => @returnM CompM _ (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_exsh0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_exsh0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit))) (@existT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_ex0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex1 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex1 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit)) (@projT1 (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_elimEx0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_elimEx0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit)) call_ret_val) (pair (SAWCoreScaffolding.fst (@projT2 (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_elimEx0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_elimEx0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit)) call_ret_val)) (pair (SAWCoreScaffolding.fst (SAWCoreScaffolding.snd (@projT2 (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_elimEx0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => prod (@SAWCorePrelude.BVVec 64 x_elimEx0 (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 8 (@SAWCoreScaffolding.Bool)) => unit))) (prod (@sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) unit)) call_ret_val))) tt))))))) tt). diff --git a/heapster-saw/examples/rust_lifetimes.v b/heapster-saw/examples/rust_lifetimes.v index 38dbdc92e0..dd4983ae6f 100644 --- a/heapster-saw/examples/rust_lifetimes.v +++ b/heapster-saw/examples/rust_lifetimes.v @@ -41,9 +41,10 @@ Definition unfoldListPermH : forall (a : Type), @Datatypes.list a -> @SAWCorePre Definition foldListPermH : forall (a : Type), @SAWCorePrelude.Either unit (prod unit (prod a (@Datatypes.list a))) -> @Datatypes.list a := fun (a : Type) => @SAWCorePrelude.either unit (prod unit (prod a (@Datatypes.list a))) (@Datatypes.list a) (fun (_1 : unit) => @Datatypes.nil a) (fun (tup : prod unit (prod a (@Datatypes.list a))) => @Datatypes.cons a (SAWCoreScaffolding.fst (SAWCoreScaffolding.snd tup)) (SAWCoreScaffolding.snd (SAWCoreScaffolding.snd tup))). -Definition llvm__x2euadd__x2ewith__x2eoverflow__x2ei64 : forall (p0 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)), forall (p1 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in - let var__1 := @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool) in - CompM (prod (@sigT var__0 (fun (x_ex0 : var__0) => unit)) (prod (@sigT var__1 (fun (x_ex0 : var__1) => unit)) unit)) := +Definition llvm__x2euadd__x2ewith__x2eoverflow__x2ei64 : forall (p0 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)), forall (p1 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)), let var__0 := forall (a : Type), forall (b : a -> Type), Type in + let var__1 := @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool) in + let var__2 := @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool) in + CompM (prod (@sigT var__1 (fun (x_ex0 : var__1) => unit)) (prod (@sigT var__2 (fun (x_ex0 : var__2) => unit)) unit)) := fun (x : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (_1 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) (y : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) (fun (_1 : @SAWCoreVectorsAsCoqVectors.Vec 64 (@SAWCoreScaffolding.Bool)) => unit)) => @returnM CompM _ (prod int64Trans (prod int1Trans unit)) (pair (@mkInt64Trans (@SAWCoreVectorsAsCoqVectors.bvAdd 64 (@unInt64Trans x) (@unInt64Trans y))) (pair (@mkInt1Trans (@SAWCoreVectorsAsCoqVectors.gen 1 (@SAWCoreScaffolding.Bool) (fun (_1 : @SAWCoreScaffolding.Nat) => @SAWCorePrelude.bvCarry 64 (@unInt64Trans x) (@unInt64Trans y)))) tt)). Definition llvm__x2eexpect__x2ei1 : forall (p0 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)), forall (p1 : @sigT (@SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) (fun (x_ex0 : @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool)) => unit)), let var__0 := @SAWCoreVectorsAsCoqVectors.Vec 1 (@SAWCoreScaffolding.Bool) in diff --git a/heapster-saw/src/Verifier/SAW/Heapster/CruUtil.hs b/heapster-saw/src/Verifier/SAW/Heapster/CruUtil.hs index 9824b5d26f..693e98d874 100644 --- a/heapster-saw/src/Verifier/SAW/Heapster/CruUtil.hs +++ b/heapster-saw/src/Verifier/SAW/Heapster/CruUtil.hs @@ -489,6 +489,22 @@ assignToRList asgn = case viewAssign asgn of AssignEmpty -> MNil AssignExtend asgn' f -> assignToRList asgn' :>: f +-- | Invert 'assignToRList', converting a Hobbits 'RAssign' over a Hobbits +-- context generated by 'CtxToRList' back to a Crucible 'Assignment' +unAssignToRList :: Assignment prx ctx -> RAssign f (CtxToRList ctx) -> + Assignment f ctx +unAssignToRList ctx fs = + let sz = Ctx.size ctx in + Ctx.generate sz $ \ix -> RL.get (indexToMember sz ix) fs + +-- | Append two Hobbits 'RAssign's that have been generated by 'assignToRList' +assignToRListAppend :: Assignment prx1 ctx1 -> Assignment prx2 ctx2 -> + RAssign f (CtxToRList ctx1) -> + RAssign f (CtxToRList ctx2) -> + RAssign f (CtxToRList (ctx1 <+> ctx2)) +assignToRListAppend ctx1 ctx2 fs1 fs2 = + assignToRList (unAssignToRList ctx1 fs1 Ctx.<++> unAssignToRList ctx2 fs2) + -- | Convert a Crucible 'Assignment' over a context of contexts to an 'RAssign' -- over a right-list of right-lists assignToRListRList :: (forall c. f c -> g (CtxToRList c)) -> diff --git a/heapster-saw/src/Verifier/SAW/Heapster/Permissions.hs b/heapster-saw/src/Verifier/SAW/Heapster/Permissions.hs index e1b3cc6faf..fd9e7d9c20 100644 --- a/heapster-saw/src/Verifier/SAW/Heapster/Permissions.hs +++ b/heapster-saw/src/Verifier/SAW/Heapster/Permissions.hs @@ -2964,6 +2964,57 @@ isConjPerm (ValPerm_Named n _ _) = nameSortIsConj (namedPermNameSort n) isConjPerm (ValPerm_Var _ _) = False isConjPerm (ValPerm_Conj _) = True +-- | Return a struct permission where all fields have @true@ permissions +trueStructAtomicPerm :: Assignment prx ctx -> AtomicPerm (StructType ctx) +trueStructAtomicPerm = + Perm_Struct . RL.map (const ValPerm_True). assignToRList + +-- | Take two list of atomic struct permissions, one for structs with fields +-- given by @ctx1@ and one with those given by @ctx2@, and append them pointwise +-- to get a list of atomic struct permissions whose fields are given by the +-- append @ctx1 <+> ctx2@. If one list is shorter than the other, fill it out +-- with struct permissions @struct (true, ..., true)@ of all @true@ permissions. +-- This only works if both lists have only 'Perm_Struct' permissions, and +-- otherwise return 'Nothing'. +tryAppendStructAPerms :: Assignment prx1 ctx1 -> Assignment prx2 ctx2 -> + [AtomicPerm (StructType ctx1)] -> + [AtomicPerm (StructType ctx2)] -> + Maybe [AtomicPerm (StructType (ctx1 <+> ctx2))] +tryAppendStructAPerms _ _ [] [] = return [] +tryAppendStructAPerms ctx1 ctx2 (Perm_Struct fs_ps:ps) (Perm_Struct fs_qs:qs) = + (Perm_Struct (assignToRListAppend ctx1 ctx2 fs_ps fs_qs) :) <$> + tryAppendStructAPerms ctx1 ctx2 ps qs +tryAppendStructAPerms ctx1 ctx2 [] qs = + tryAppendStructAPerms ctx1 ctx2 [trueStructAtomicPerm ctx1] qs +tryAppendStructAPerms ctx1 ctx2 ps [] = + tryAppendStructAPerms ctx1 ctx2 ps [trueStructAtomicPerm ctx2] +tryAppendStructAPerms _ _ _ _ = mzero + +-- | Try to append struct permissions for structs with fields given by @ctx1@ +-- and @ctx2@ to get a permission for structs with fields given by the append +-- @ctx1 <+> ctx2@ of these two contexts. Return 'Nothing' if this is not +-- possible. +tryAppendStructPerms :: Assignment prx1 ctx1 -> Assignment prx2 ctx2 -> + ValuePerm (StructType ctx1) -> + ValuePerm (StructType ctx2) -> + Maybe (ValuePerm (StructType (ctx1 <+> ctx2))) +tryAppendStructPerms ctx1 ctx2 (ValPerm_Or p1 p2) q = + ValPerm_Or <$> tryAppendStructPerms ctx1 ctx2 p1 q <*> + tryAppendStructPerms ctx1 ctx2 p2 q +tryAppendStructPerms ctx1 ctx2 p (ValPerm_Or q1 q2) = + ValPerm_Or <$> tryAppendStructPerms ctx1 ctx2 p q1 <*> + tryAppendStructPerms ctx1 ctx2 p q2 +tryAppendStructPerms ctx1 ctx2 (ValPerm_Exists mb_p) q = + ValPerm_Exists <$> mbMaybe (flip fmap mb_p $ \p -> + tryAppendStructPerms ctx1 ctx2 p q) +tryAppendStructPerms ctx1 ctx2 p (ValPerm_Exists mb_q) = + ValPerm_Exists <$> mbMaybe (flip fmap mb_q $ \q -> + tryAppendStructPerms ctx1 ctx2 p q) +tryAppendStructPerms ctx1 ctx2 (ValPerm_Conj ps) (ValPerm_Conj qs) = + ValPerm_Conj <$> tryAppendStructAPerms ctx1 ctx2 ps qs +tryAppendStructPerms _ _ _ _ = mzero + + -- | Helper function to build a 'Perm_LLVMFunPtr' from a 'FunPerm' mkPermLLVMFunPtr :: (1 <= w, KnownNat w) => f w -> FunPerm ghosts args ret -> AtomicPerm (LLVMPointerType w) diff --git a/heapster-saw/src/Verifier/SAW/Heapster/RustTypes.hs b/heapster-saw/src/Verifier/SAW/Heapster/RustTypes.hs index 78afe0280e..b6c621aab0 100644 --- a/heapster-saw/src/Verifier/SAW/Heapster/RustTypes.hs +++ b/heapster-saw/src/Verifier/SAW/Heapster/RustTypes.hs @@ -42,6 +42,10 @@ import qualified Control.Monad.Fail as Fail import Data.Parameterized.BoolRepr import Data.Parameterized.Some +import Data.Parameterized.Context (Assignment, IsAppend(..), + incSize, zeroSize, sizeInt, + size, generate, extend) +import qualified Data.Parameterized.Context as Ctx import Data.Binding.Hobbits import Data.Binding.Hobbits.MonadBind @@ -504,35 +508,120 @@ instance RsConvert w (StructField Span) (PermExpr (LLVMShapeType w)) where -- * Computing the ABI-Specific Layout of Rust Types ---------------------------------------------------------------------- --- | An argument layout is a sequence of Crucible types for 0 or more function --- arguments along with permissions on them, which could be existential in some --- number of ghost arguments. The ghost arguments cannot have permissions on --- them, so that we can create struct permissions from just the arg perms. +-- | An 'ArgLayoutPerm' is a set of permissions on a sequence of 0 or more +-- arguments, given by the @tps@ type-level argument. These permissions are +-- similar to the language of permissions on a Crucible struct, except that the +-- langauge is restricted to ensure that they can always be appended. +data ArgLayoutPerm ctx where + ALPerm :: RAssign ValuePerm (CtxToRList ctx) -> ArgLayoutPerm ctx + ALPerm_Or :: ArgLayoutPerm ctx -> ArgLayoutPerm ctx -> ArgLayoutPerm ctx + ALPerm_Exists :: KnownRepr TypeRepr a => + Binding a (ArgLayoutPerm ctx) -> ArgLayoutPerm ctx + +-- | Build an 'ArgLayoutPerm' that just assigns @true@ to every field +trueArgLayoutPerm :: Assignment prx ctx -> ArgLayoutPerm ctx +trueArgLayoutPerm ctx = ALPerm (RL.map (const ValPerm_True) $ assignToRList ctx) + +-- | Build an 'ArgLayoutPerm' for 0 fields +argLayoutPerm0 :: ArgLayoutPerm EmptyCtx +argLayoutPerm0 = ALPerm MNil + +-- | Build an 'ArgLayoutPerm' for a single field +argLayoutPerm1 :: ValuePerm a -> ArgLayoutPerm (EmptyCtx '::> a) +argLayoutPerm1 p = ALPerm (MNil :>: p) + +-- | Convert an 'ArgLayoutPerm' to a permission on a struct +argLayoutPermToPerm :: ArgLayoutPerm ctx -> ValuePerm (StructType ctx) +argLayoutPermToPerm (ALPerm ps) = ValPerm_Conj1 $ Perm_Struct ps +argLayoutPermToPerm (ALPerm_Or p1 p2) = + ValPerm_Or (argLayoutPermToPerm p1) (argLayoutPermToPerm p2) +argLayoutPermToPerm (ALPerm_Exists mb_p) = + ValPerm_Exists $ fmap argLayoutPermToPerm mb_p + +-- | Convert an 'ArgLayoutPerm' on a single field to a permission on single +-- values of the type of that field +argLayoutPerm1ToPerm :: ArgLayoutPerm (EmptyCtx '::> a) -> ValuePerm a +argLayoutPerm1ToPerm (ALPerm (_ :>: p)) = p +argLayoutPerm1ToPerm (ALPerm_Or p1 p2) = + ValPerm_Or (argLayoutPerm1ToPerm p1) (argLayoutPerm1ToPerm p2) +argLayoutPerm1ToPerm (ALPerm_Exists mb_p) = + ValPerm_Exists $ fmap argLayoutPerm1ToPerm mb_p + +-- | Append the field types @ctx1@ and @ctx2@ of two 'ArgLayoutPerm's to get a +-- combined 'ArgLayoutPerm' over the combined fields +appendArgLayoutPerms :: Assignment prx1 ctx1 -> Assignment prx2 ctx2 -> + ArgLayoutPerm ctx1 -> ArgLayoutPerm ctx2 -> + ArgLayoutPerm (ctx1 <+> ctx2) +appendArgLayoutPerms ctx1 ctx2 (ALPerm_Or p1 p2) q = + ALPerm_Or (appendArgLayoutPerms ctx1 ctx2 p1 q) + (appendArgLayoutPerms ctx1 ctx2 p2 q) +appendArgLayoutPerms ctx1 ctx2 p (ALPerm_Or q1 q2) = + ALPerm_Or (appendArgLayoutPerms ctx1 ctx2 p q1) + (appendArgLayoutPerms ctx1 ctx2 p q2) +appendArgLayoutPerms ctx1 ctx2 (ALPerm_Exists mb_p) q = + ALPerm_Exists $ fmap (\p -> appendArgLayoutPerms ctx1 ctx2 p q) mb_p +appendArgLayoutPerms ctx1 ctx2 p (ALPerm_Exists mb_q) = + ALPerm_Exists $ fmap (\q -> appendArgLayoutPerms ctx1 ctx2 p q) mb_q +appendArgLayoutPerms ctx1 ctx2 (ALPerm ps) (ALPerm qs) = + ALPerm $ assignToRListAppend ctx1 ctx2 ps qs + +-- | An argument layout captures how argument values are laid out as a Crucible +-- struct of 0 or more machine words / fields data ArgLayout where - ArgLayout :: KnownCruCtx ghosts -> KnownCruCtx args -> - Mb ghosts (ValuePerms args) -> ArgLayout + ArgLayout :: CtxRepr ctx -> ArgLayoutPerm ctx -> ArgLayout -instance Semigroup ArgLayout where - ArgLayout ghosts1 args1 mb_ps1 <> ArgLayout ghosts2 args2 mb_ps2 = - ArgLayout (RL.append ghosts1 ghosts2) (RL.append args1 args2) $ - mbCombine (RL.mapRAssign (const Proxy) ghosts2) $ - fmap (\ps1 -> fmap (\ps2 -> RL.append ps1 ps2) mb_ps2) mb_ps1 +-- | Count the number of fields of an 'ArgLayout' +argLayoutNumFields :: ArgLayout -> Int +argLayoutNumFields (ArgLayout ctx _) = sizeInt $ size ctx -instance Monoid ArgLayout where - mempty = ArgLayout MNil MNil (emptyMb $ MNil) +-- | Construct an 'ArgLayout' for 0 arguments +argLayout0 :: ArgLayout +argLayout0 = ArgLayout Ctx.empty (ALPerm MNil) --- | Construct an 'ArgLayout' for a single argument with no ghost variables +-- | Construct an 'ArgLayout' for a single argument argLayout1 :: KnownRepr TypeRepr a => ValuePerm a -> ArgLayout -argLayout1 p = - ArgLayout MNil (MNil :>: KnownReprObj) $ emptyMb (MNil :>: p) - --- | Convert an 'ArgLayout' in a name-binding into an 'ArgLayout' with an --- additional ghost argument for the bound name -mbArgLayout :: KnownRepr TypeRepr a => Binding a ArgLayout -> ArgLayout -mbArgLayout (mbMatch -> [nuMP| ArgLayout ghosts args mb_ps |]) = - ArgLayout (mbLift ghosts :>: KnownReprObj) (mbLift args) - (mbCombine RL.typeCtxProxies (mbSwap (RL.mapRAssign (const Proxy) (mbLift ghosts)) mb_ps)) - +argLayout1 p = ArgLayout (extend Ctx.empty knownRepr) (ALPerm (MNil :>: p)) + +-- | Append two 'ArgLayout's, if possible +appendArgLayout :: ArgLayout -> ArgLayout -> ArgLayout +appendArgLayout (ArgLayout ctx1 p1) (ArgLayout ctx2 p2) = + ArgLayout (ctx1 Ctx.<++> ctx2) (appendArgLayoutPerms ctx1 ctx2 p1 p2) + +-- | Test if @ctx2@ is an extension of @ctx1@ +ctxIsAppend :: CtxRepr ctx1 -> CtxRepr ctx2 -> + Maybe (IsAppend ctx1 ctx2) +ctxIsAppend ctx1 ctx2 + | Just Refl <- testEquality ctx1 ctx2 + = Just $ IsAppend zeroSize +ctxIsAppend ctx1 (ctx2' Ctx.:> _) + | Just (IsAppend sz) <- ctxIsAppend ctx1 ctx2' + = Just (IsAppend (incSize sz)) +ctxIsAppend _ _ = Nothing + +-- | Take the disjunction of two 'ArgLayout's, if possible +disjoinArgLayouts :: ArgLayout -> ArgLayout -> Maybe ArgLayout +disjoinArgLayouts (ArgLayout ctx1 p1) (ArgLayout ctx2 p2) + | Just (IsAppend sz') <- ctxIsAppend ctx1 ctx2 = + let ps' = generate sz' (const ValPerm_True) in + Just $ ArgLayout ctx2 $ + ALPerm_Or + (appendArgLayoutPerms ctx1 ps' p1 (ALPerm $ assignToRList ps')) + p2 +disjoinArgLayouts (ArgLayout ctx1 p1) (ArgLayout ctx2 p2) + | Just (IsAppend sz') <- ctxIsAppend ctx2 ctx1 = + let ps' = generate sz' (const ValPerm_True) in + Just $ ArgLayout ctx1 $ + ALPerm_Or + p1 + (appendArgLayoutPerms ctx2 ps' p2 (ALPerm $ assignToRList ps')) +disjoinArgLayouts _ _ = Nothing + +-- | Make an existential 'ArgLayout' +existsArgLayout :: KnownRepr TypeRepr a => Binding a ArgLayout -> ArgLayout +existsArgLayout [nuP| ArgLayout mb_ctx mb_p |] = + ArgLayout (mbLift mb_ctx) (ALPerm_Exists mb_p) + +{- -- | Convert an 'ArgLayout' to a permission on a @struct@ of its arguments argLayoutStructPerm :: ArgLayout -> Some (Typed ValuePerm) argLayoutStructPerm (ArgLayout ghosts (MNil :>: KnownReprObj) mb_perms) = @@ -543,6 +632,7 @@ argLayoutStructPerm (ArgLayout ghosts args mb_perms) , Refl <- cruCtxToReprEq (knownCtxToCruCtx args) = Some $ Typed (StructRepr args_repr) $ valPermExistsMulti ghosts $ fmap (ValPerm_Conj1 . Perm_Struct) mb_perms +-} -- | Convert a shape to a writeable block permission with that shape, or fail if -- the length of the shape is not defined @@ -591,18 +681,47 @@ un3SomeFunPerm args ret (Some3FunPerm fun_perm) = <+> pretty "=>" <+> PP.group (permPretty emptyPPInfo (funPermRet fun_perm)) ] --- | Build a function permission from an 'ArgLayout' plus return permission -funPerm3FromArgLayout :: ArgLayout -> TypeRepr ret -> ValuePerm ret -> - Some3FunPerm -funPerm3FromArgLayout (ArgLayout ghosts args mb_arg_perms) ret_tp ret_perm = - let gs_args_prxs = RL.map (const Proxy) (RL.append ghosts args) in - Some3FunPerm $ FunPerm (knownCtxToCruCtx ghosts) (knownCtxToCruCtx args) - ret_tp - (extMbMulti (RL.map (\_ -> Proxy) args) $ - fmap (RL.append $ RL.map (const ValPerm_True) ghosts) mb_arg_perms) - (nuMulti (gs_args_prxs :>: Proxy) $ const - (RL.map (const ValPerm_True) gs_args_prxs :>: ret_perm)) - +-- | Build a function permission from an 'ArgLayout' that describes the +-- arguments and their input permissions and a return permission that describes +-- the output permissions on the return value. The arguments specified by the +-- 'ArgLayout' get no permissions on output. The caller also specifies +-- additional arguments to be prepended to the argument list that do have output +-- permissions as a struct of 0 or more fields along with input and output +-- permissions on those arguments. +funPerm3FromArgLayout :: ArgLayout -> CtxRepr args -> + ValuePerms (CtxToRList args) -> + ValuePerms (CtxToRList args) -> + TypeRepr ret -> ValuePerm ret -> + RustConvM Some3FunPerm +funPerm3FromArgLayout (ArgLayout ctx p_in) ctx1 ps1_in ps1_out ret_tp ret_perm + -- Special case: if the argument perms are just a sequence of permissions on + -- the individual arguments, make a function perm with those argument perms, + -- that is, we build the function permission + -- + -- (). arg1:p1, ..., argn:pn -o ret:ret_perm + | ALPerm ps_in <- p_in + , ctx_all <- mkCruCtx (ctx1 Ctx.<++> ctx) + , ps_in_all <- RL.append MNil (assignToRListAppend ctx1 ctx ps1_in ps_in) + , ps_out_all <- + RL.append MNil (assignToRListAppend ctx1 ctx ps1_out $ + trueValuePerms $ assignToRList ctx) :>: ret_perm + , gs_ctx_prxs <- RL.append MNil (cruCtxProxies ctx_all) = + return $ Some3FunPerm $ FunPerm CruCtxNil ctx_all ret_tp + (nuMulti gs_ctx_prxs $ \_ -> ps_in_all) + (nuMulti (gs_ctx_prxs :>: Proxy) $ \_ -> ps_out_all) +funPerm3FromArgLayout (ArgLayout _ctx _p) _ctx1 _p1_in _p1_out _ret_tp _ret_perm = + -- FIXME HERE + fail "Cannot (yet) handle Rust enums or other disjunctive types in functions" + +-- | Like 'funPerm3FromArgLayout' but with no additional arguments +funPerm3FromArgLayoutNoArgs :: ArgLayout -> TypeRepr ret -> ValuePerm ret -> + RustConvM Some3FunPerm +funPerm3FromArgLayoutNoArgs layout ret ret_perm = + funPerm3FromArgLayout layout Ctx.empty MNil MNil ret ret_perm + + +-- FIXME: should we save any of these? +{- -- | Extend a name binding by adding a name in the middle extMbMiddle :: forall prx1 ctx1 prx2 ctx2 prxb a b. @@ -636,6 +755,7 @@ funPerm3PrependArg arg_tp arg_in arg_out (Some3FunPerm fmap (rassignInsertMiddle ghosts args_prxs arg_in) ps_in) (extMbMiddle ghosts (args_prxs :>: Proxy) arg_tp $ fmap (rassignInsertMiddle ghosts (args_prxs :>: Proxy) arg_out) ps_out) +-} mbSeparatePrx :: prx1 ctx1 -> RAssign prx2 ctx2 -> Mb (ctx1 :++: ctx2) a -> Mb ctx1 (Mb ctx2 a) @@ -689,6 +809,7 @@ mbGhostsFunPerm3 new_ghosts (mbMatch -> [nuMP| Some3FunPerm ghosts_prxs (args_prxs :>: Proxy)) $ mbCombine (RL.append ghosts_prxs args_prxs :>: Proxy) ps_out) + -- | Try to compute the layout of a structure of the given shape as a value, -- over 1 or more registers, if this is possible layoutArgShapeByVal :: (1 <= w, KnownNat w) => Abi -> @@ -696,7 +817,7 @@ layoutArgShapeByVal :: (1 <= w, KnownNat w) => Abi -> MaybeT RustConvM ArgLayout -- The empty shape --> no values -layoutArgShapeByVal Rust PExpr_EmptyShape = return mempty +layoutArgShapeByVal Rust PExpr_EmptyShape = return argLayout0 -- Named shapes that unfold --> layout their unfoldings layoutArgShapeByVal Rust (PExpr_NamedShape rw l nmsh args) @@ -745,30 +866,27 @@ layoutArgShapeByVal Rust (PExpr_ArrayShape _ _ _) = mzero layoutArgShapeByVal Rust (PExpr_SeqShape sh1 sh2) = do layout1 <- layoutArgShapeByVal Rust sh1 layout2 <- layoutArgShapeByVal Rust sh2 - case (mappend layout1 layout2) of - layout@(ArgLayout _ args _) - | length (RL.mapToList (const Proxy) args) <= 2 -> return layout - _ -> mzero + let layout = appendArgLayout layout1 layout2 + if argLayoutNumFields layout <= 2 then return layout else mzero -- Disjunctive shapes are only laid out as values in the Rust ABI if both sides --- have the same number and sizes of arguments. Note that Heapster currently --- cannot handle this optimization, and so this is an error, but if the shape --- cannot be laid out as values then we return Nothing without an error. -layoutArgShapeByVal Rust sh@(PExpr_OrShape sh1 sh2) = +-- can be laid out as values that we can coerce to have the same number of type +-- of fields. +-- +-- FIXME: The check for whether we can do this coercion is currently done by +-- disjoinArgLayouts, but it is probably ABI-specific, so should be performed by +-- a function that knows how to join two lists of field types depending on the +-- ABI +layoutArgShapeByVal Rust (PExpr_OrShape sh1 sh2) = do layout1 <- layoutArgShapeByVal Rust sh1 layout2 <- layoutArgShapeByVal Rust sh2 - case (layout1, layout2) of - (ArgLayout _ args1 _, ArgLayout _ args2 _) - | Just Refl <- - testEquality (knownCtxToCruCtx args1) (knownCtxToCruCtx args2) -> - lift $ fail $ renderDoc $ fillSep - [pretty "layoutArgShapeByVal: Optimizing disjunctive shapes not yet supported for shape:", - permPretty emptyPPInfo sh] - _ -> mzero + case disjoinArgLayouts layout1 layout2 of + Just layout -> return layout + Nothing -> mzero -- For existential shapes, just add the existential variable to the ghosts layoutArgShapeByVal Rust (PExpr_ExShape mb_sh) = - mbArgLayout <$> mbM (fmap (layoutArgShapeByVal Rust) mb_sh) + existsArgLayout <$> mbM (fmap (layoutArgShapeByVal Rust) mb_sh) layoutArgShapeByVal Rust sh = lift $ fail $ renderDoc $ fillSep @@ -807,18 +925,25 @@ layoutFun :: (1 <= w, KnownNat w) => Abi -> [PermExpr (LLVMShapeType w)] -> PermExpr (LLVMShapeType w) -> RustConvM Some3FunPerm layoutFun abi arg_shs ret_sh = - do args_layout <- mconcat <$> mapM (layoutArgShape abi) arg_shs + do args_layout <- + foldr appendArgLayout argLayout0 <$> mapM (layoutArgShape abi) arg_shs ret_layout_eith <- layoutArgShapeOrBlock abi ret_sh case ret_layout_eith of - Right ret_layout - | Some (Typed ret_tp ret_p) <- argLayoutStructPerm ret_layout -> - return $ funPerm3FromArgLayout args_layout ret_tp ret_p + Right (ArgLayout (Ctx.Empty Ctx.:> ret_tp) + (argLayoutPerm1ToPerm -> ret_p)) -> + -- Special case: if the return type is a single field, remove the + -- struct type and just use the type of that single field + funPerm3FromArgLayoutNoArgs args_layout ret_tp ret_p + Right (ArgLayout ret_ctx ret_p) -> + funPerm3FromArgLayoutNoArgs args_layout (StructRepr ret_ctx) + (argLayoutPermToPerm ret_p) Left bp -> - return $ - funPerm3PrependArg knownRepr - (ValPerm_LLVMBlock $ bp { llvmBlockShape = PExpr_EmptyShape}) - (ValPerm_LLVMBlock bp) $ - funPerm3FromArgLayout args_layout UnitRepr ValPerm_True + funPerm3FromArgLayout args_layout + (extend Ctx.empty knownRepr) + (MNil :>: ValPerm_LLVMBlock (bp { llvmBlockShape = + PExpr_EmptyShape})) + (MNil :>: ValPerm_LLVMBlock bp) + UnitRepr ValPerm_True ---------------------------------------------------------------------- @@ -1025,6 +1150,8 @@ parseNamedShapeFromRustDecl env w str parseNamedShapeFromRustDecl _ _ str = fail ("Malformed Rust type: " ++ str) + +$(mkNuMatching [t| forall ctx. ArgLayoutPerm ctx |]) $(mkNuMatching [t| ArgLayout |]) $(mkNuMatching [t| Some3FunPerm |]) $(mkNuMatching [t| forall a. NuMatching a => SomeTypedMb a |]) From d2f1c38bf061b9cddb16efb64f15917da018a9e8 Mon Sep 17 00:00:00 2001 From: Eddy Westbrook Date: Wed, 30 Jun 2021 12:37:07 -0700 Subject: [PATCH 2/2] uncommented the line for printing list_head_impl__tuple_fun because it works now --- heapster-saw/examples/rust_data_proofs.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/heapster-saw/examples/rust_data_proofs.v b/heapster-saw/examples/rust_data_proofs.v index 120cac2005..4623e67ae9 100644 --- a/heapster-saw/examples/rust_data_proofs.v +++ b/heapster-saw/examples/rust_data_proofs.v @@ -23,7 +23,7 @@ Print list_is_empty__tuple_fun. Print list_head__tuple_fun. -(* Print list_head_impl__tuple_fun. *) +Print list_head_impl__tuple_fun. Print str_struct_new__tuple_fun.