| (* |
| * Copyright 2016, NICTA |
| * |
| * This software may be distributed and modified according to the terms of |
| * the GNU General Public License version 2. Note that NO WARRANTY is provided. |
| * See "LICENSE_GPLv2.txt" for details. |
| * |
| * @TAG(NICTA_GPL) |
| *) |
| |
| (* |
| * Testcase for higher-order functions. |
| * |
| * Sources: loop.cogent loop.ac |
| * To generate: |
| * cogent -gloopmain loop.cogent --infer-c-func=loop.ac --table-c-types=loopfull.table |
| * cat loopmain.c loop_pp_inferred.c > loopfull.c |
| * gcc loopfull.c -o loopfull -I../../cogent/lib && ./loopfull |
| * cogent --type-proof=Loop --fml-typing-tree loop.cogent |
| * |
| * |
| * The loop combinator (seq32_0) is a second-order function. |
| * In this program, it is called with id_loopbody and triangular_loopbody |
| * as arguments. |
| * |
| * Logical call graph: |
| * triangular \<rightarrow> seq32_0 \<rightarrow> triangular_loopbody \<rightarrow> id_f \<rightarrow> seq32_0 \<rightarrow> id_loopbody |
| * |
| * C call graph: |
| * triangular \<rightarrow> seq32_0 \<rightarrow> dispatch_t2 \<rightarrow> |
| * triangular_loopbody \<rightarrow> id_f \<rightarrow> seq32_0 \<rightarrow> dispatch_t2 \<rightarrow> id_loopbody |
| * |
| * We verify the program in bottom-up order, starting with id_loopbody. |
| * We first verify seq32_0 with dispatch_t2 specialised to id_loopbody, |
| * which allows us to verify id_f and triangular_loopbody. |
| * Then, we verify seq32_0 with dispatch_t2 specialised to triangular_loopbody, |
| * which allows us to verify triangular. |
| *) |
| theory Loop |
| imports |
| "../CogentHigherOrder" |
| "../Corres_Tac" |
| "../TypeProofGen" |
| "../Type_Relation_Generation" |
| "../Deep_Embedding_Auto" |
| "../Tidy" |
| begin |
| |
| (* |
| This file is generated by Cogent version 2.3.0.0-cee676104d |
| with command ./cogent --type-proof=Loop --fml-typing-tree loop.cogent |
| at Fri, 15 May 2015 17:30:31 AEST |
| *) |
| |
| definition |
| "abbreviatedType1 \<equiv> TRecord [(TPrim (Num U32), False), (TPrim (Num U32), False)] Unboxed" |
| |
| lemmas abbreviated_type_defs = |
| abbreviatedType1_def |
| |
| definition |
| "seq32_0_type \<equiv> ([], (TRecord [(TPrim (Num U32), False), (TPrim (Num U32), False), (TFun abbreviatedType1 (TPrim (Num U32)), False), (TPrim (Num U32), False)] Unboxed, TPrim (Num U32)))" |
| |
| definition |
| "id_loopbody_type \<equiv> ([], (abbreviatedType1, TPrim (Num U32)))" |
| |
| definition |
| "id_loopbody \<equiv> Take (Var 0) 0 (Take (Var 1) 1 (Let (Lit (LU8 1)) (Let (Cast U32 (Var 0)) (Prim (Plus U32) [Var 4, Var 0]))))" |
| |
| definition |
| "id_f_type \<equiv> ([], (TPrim (Num U32), TPrim (Num U32)))" |
| |
| definition |
| "id_f \<equiv> Let (Var 0) (Let (Lit (LU8 0)) (Let (Cast U32 (Var 0)) (Let (Fun id_loopbody []) (Let (Lit (LU8 0)) (Let (Cast U32 (Var 0)) (Let (Struct [TPrim (Num U32), TPrim (Num U32), TFun abbreviatedType1 (TPrim (Num U32)), TPrim (Num U32)] [Var 3, Var 5, Var 2, Var 0]) (App (AFun ''seq32_0'' []) (Var 0))))))))" |
| |
| definition |
| "triangular_loopbody_type \<equiv> ([], (abbreviatedType1, TPrim (Num U32)))" |
| |
| definition |
| "triangular_loopbody \<equiv> Take (Var 0) 0 (Take (Var 1) 1 (Let (App (Fun id_f []) (Var 0)) (Prim (Plus U32) [Var 3, Var 0])))" |
| |
| definition |
| "triangular_type \<equiv> ([], (TPrim (Num U32), TPrim (Num U32)))" |
| |
| definition |
| "triangular \<equiv> Let (Var 0) (Let (Lit (LU8 0)) (Let (Cast U32 (Var 0)) (Let (Fun triangular_loopbody []) (Let (Lit (LU8 0)) (Let (Cast U32 (Var 0)) (Let (Struct [TPrim (Num U32), TPrim (Num U32), TFun abbreviatedType1 (TPrim (Num U32)), TPrim (Num U32)] [Var 3, Var 5, Var 2, Var 0]) (App (AFun ''seq32_0'' []) (Var 0))))))))" |
| |
| ML {* |
| val Cogent_functions = ["id_loopbody","id_f","triangular_loopbody","triangular"] |
| val Cogent_abstract_functions = ["seq32_0"] |
| *} |
| |
| definition |
| "\<Xi> func_name' \<equiv> case func_name' of ''seq32_0'' \<Rightarrow> seq32_0_type | ''id_loopbody'' \<Rightarrow> id_loopbody_type | ''id_f'' \<Rightarrow> id_f_type | ''triangular_loopbody'' \<Rightarrow> triangular_loopbody_type | ''triangular'' \<Rightarrow> triangular_type" |
| |
| definition |
| "\<xi> func_name' \<equiv> case func_name' of ''seq32_0'' \<Rightarrow> undefined" |
| |
| definition |
| "id_loopbody_typetree \<equiv> TyTrSplit (Cons (Some TSK_L) []) [] TyTrLeaf [Some (TPrim (Num U32)), Some (TRecord [(TPrim (Num U32), True), (TPrim (Num U32), False)] Unboxed)] (TyTrSplit (Cons None (Cons (Some TSK_L) (Cons None []))) [] TyTrLeaf [Some (TPrim (Num U32)), Some (TRecord [(TPrim (Num U32), True), (TPrim (Num U32), True)] Unboxed)] (TyTrSplit (Cons (Some TSK_L) (Cons (Some TSK_L) (append (replicate 3 None) []))) [] TyTrLeaf [Some (TPrim (Num U8))] (TyTrSplit (Cons (Some TSK_L) (append (replicate 5 None) [])) [] TyTrLeaf [Some (TPrim (Num U32))] TyTrLeaf)))" |
| |
| definition |
| "id_f_typetree \<equiv> TyTrSplit (Cons (Some TSK_L) []) [] TyTrLeaf [Some (TPrim (Num U32))] (TyTrSplit (append (replicate 2 None) []) [] TyTrLeaf [Some (TPrim (Num U8))] (TyTrSplit (Cons (Some TSK_L) (append (replicate 2 None) [])) [] TyTrLeaf [Some (TPrim (Num U32))] (TyTrSplit (append (replicate 4 None) []) [] TyTrLeaf [Some (TFun abbreviatedType1 (TPrim (Num U32)))] (TyTrSplit (append (replicate 5 None) []) [] TyTrLeaf [Some (TPrim (Num U8))] (TyTrSplit (Cons (Some TSK_L) (append (replicate 5 None) [])) [] TyTrLeaf [Some (TPrim (Num U32))] (TyTrSplit (Cons (Some TSK_L) (Cons None (Cons (Some TSK_L) (Cons (Some TSK_L) (Cons None (Cons (Some TSK_L) (Cons None []))))))) [] TyTrLeaf [Some (TRecord [(TPrim (Num U32), False), (TPrim (Num U32), False), (TFun abbreviatedType1 (TPrim (Num U32)), False), (TPrim (Num U32), False)] Unboxed)] TyTrLeaf))))))" |
| |
| definition |
| "triangular_loopbody_typetree \<equiv> TyTrSplit (Cons (Some TSK_L) []) [] TyTrLeaf [Some (TPrim (Num U32)), Some (TRecord [(TPrim (Num U32), True), (TPrim (Num U32), False)] Unboxed)] (TyTrSplit (Cons None (Cons (Some TSK_L) (Cons None []))) [] TyTrLeaf [Some (TPrim (Num U32)), Some (TRecord [(TPrim (Num U32), True), (TPrim (Num U32), True)] Unboxed)] (TyTrSplit (Cons (Some TSK_L) (Cons (Some TSK_L) (append (replicate 3 None) []))) [] TyTrLeaf [Some (TPrim (Num U32))] TyTrLeaf))" |
| |
| definition |
| "triangular_typetree \<equiv> TyTrSplit (Cons (Some TSK_L) []) [] TyTrLeaf [Some (TPrim (Num U32))] (TyTrSplit (append (replicate 2 None) []) [] TyTrLeaf [Some (TPrim (Num U8))] (TyTrSplit (Cons (Some TSK_L) (append (replicate 2 None) [])) [] TyTrLeaf [Some (TPrim (Num U32))] (TyTrSplit (append (replicate 4 None) []) [] TyTrLeaf [Some (TFun abbreviatedType1 (TPrim (Num U32)))] (TyTrSplit (append (replicate 5 None) []) [] TyTrLeaf [Some (TPrim (Num U8))] (TyTrSplit (Cons (Some TSK_L) (append (replicate 5 None) [])) [] TyTrLeaf [Some (TPrim (Num U32))] (TyTrSplit (Cons (Some TSK_L) (Cons None (Cons (Some TSK_L) (Cons (Some TSK_L) (Cons None (Cons (Some TSK_L) (Cons None []))))))) [] TyTrLeaf [Some (TRecord [(TPrim (Num U32), False), (TPrim (Num U32), False), (TFun abbreviatedType1 (TPrim (Num U32)), False), (TPrim (Num U32), False)] Unboxed)] TyTrLeaf))))))" |
| |
| ML {* open TTyping_Tactics *} |
| |
| ML_quiet {* |
| val typing_helper_1_script : tac list = [ |
| (RTac @{thm kind_tprim}) |
| ] *} |
| |
| |
| lemma typing_helper_1[unfolded abbreviated_type_defs] : |
| "kinding [] (TPrim (Num U32)) {E, S, D}" |
| apply (unfold abbreviated_type_defs)? |
| apply (tactic {* map (fn t => DETERM (interpret_tac t @{context} 1)) typing_helper_1_script |> EVERY *}) |
| done |
| |
| ML_quiet {* |
| val typing_helper_2_script : tac list = [ |
| (RTac @{thm kind_trec[where k = "{E,S,D}"]}), |
| (RTac @{thm kind_record_cons1}), |
| (RTac @{thm typing_helper_1}), |
| (RTac @{thm kind_record_cons1}), |
| (RTac @{thm typing_helper_1}), |
| (RTac @{thm kind_record_empty}), |
| (SimpTac ([],[])) |
| ] *} |
| |
| |
| lemma typing_helper_2[unfolded abbreviated_type_defs] : |
| "kinding [] abbreviatedType1 {E, S, D}" |
| apply (unfold abbreviated_type_defs)? |
| apply (tactic {* map (fn t => DETERM (interpret_tac t @{context} 1)) typing_helper_2_script |> EVERY *}) |
| done |
| |
| ML_quiet {* |
| val typing_helper_3_script : tac list = [ |
| (RTac @{thm kind_trec[where k = "{E,S,D}"]}), |
| (RTac @{thm kind_record_cons2}), |
| (RTac @{thm typing_helper_1}), |
| (RTac @{thm kind_record_cons1}), |
| (RTac @{thm typing_helper_1}), |
| (RTac @{thm kind_record_empty}), |
| (SimpTac ([],[])) |
| ] *} |
| |
| |
| lemma typing_helper_3[unfolded abbreviated_type_defs] : |
| "kinding [] (TRecord [(TPrim (Num U32), True), (TPrim (Num U32), False)] Unboxed) {E, S, D}" |
| apply (unfold abbreviated_type_defs)? |
| apply (tactic {* map (fn t => DETERM (interpret_tac t @{context} 1)) typing_helper_3_script |> EVERY *}) |
| done |
| |
| ML_quiet {* |
| val typing_helper_4_script : tac list = [ |
| (RTac @{thm kind_trec[where k = "{E,S,D}"]}), |
| (RTac @{thm kind_record_cons2}), |
| (RTac @{thm typing_helper_1}), |
| (RTac @{thm kind_record_cons2}), |
| (RTac @{thm typing_helper_1}), |
| (RTac @{thm kind_record_empty}), |
| (SimpTac ([],[])) |
| ] *} |
| |
| |
| lemma typing_helper_4[unfolded abbreviated_type_defs] : |
| "kinding [] (TRecord [(TPrim (Num U32), True), (TPrim (Num U32), True)] Unboxed) {E, S, D}" |
| apply (unfold abbreviated_type_defs)? |
| apply (tactic {* map (fn t => DETERM (interpret_tac t @{context} 1)) typing_helper_4_script |> EVERY *}) |
| done |
| |
| ML_quiet {* |
| val typing_helper_5_script : tac list = [ |
| (RTac @{thm kind_tprim[where k = "{E,S,D}"]}) |
| ] *} |
| |
| |
| lemma typing_helper_5[unfolded abbreviated_type_defs] : |
| "kinding [] (TPrim (Num U8)) {E, S, D}" |
| apply (unfold abbreviated_type_defs)? |
| apply (tactic {* map (fn t => DETERM (interpret_tac t @{context} 1)) typing_helper_5_script |> EVERY *}) |
| done |
| |
| ML_quiet {* |
| val typing_helper_6_script : tac list = [ |
| (RTac @{thm kind_tfun[where k = "{E,S,D}"]}), |
| (RTac @{thm typing_helper_2}), |
| (RTac @{thm typing_helper_1}) |
| ] *} |
| |
| |
| lemma typing_helper_6[unfolded abbreviated_type_defs] : |
| "kinding [] (TFun abbreviatedType1 (TPrim (Num U32))) {E, S, D}" |
| apply (unfold abbreviated_type_defs)? |
| apply (tactic {* map (fn t => DETERM (interpret_tac t @{context} 1)) typing_helper_6_script |> EVERY *}) |
| done |
| |
| ML_quiet {* |
| val typing_helper_7_script : tac list = [ |
| (SimpTac ([],[(nth @{thms HOL.simp_thms} (25-1)),(nth @{thms HOL.simp_thms} (26-1))])) |
| ] *} |
| |
| |
| lemma typing_helper_7[unfolded abbreviated_type_defs] : |
| "list_all2 (kinding []) [] []" |
| apply (unfold abbreviated_type_defs)? |
| apply (tactic {* map (fn t => DETERM (interpret_tac t @{context} 1)) typing_helper_7_script |> EVERY *}) |
| done |
| |
| ML_quiet {* |
| val typing_helper_8_script : tac list = [ |
| (RTac @{thm kind_trec[where k = "{E,S,D}"]}), |
| (RTac @{thm kind_record_cons1}), |
| (RTac @{thm typing_helper_1}), |
| (RTac @{thm kind_record_cons1}), |
| (RTac @{thm typing_helper_1}), |
| (RTac @{thm kind_record_cons1}), |
| (RTac @{thm typing_helper_6}), |
| (RTac @{thm kind_record_cons1}), |
| (RTac @{thm typing_helper_1}), |
| (RTac @{thm kind_record_empty}), |
| (SimpTac ([],[])) |
| ] *} |
| |
| |
| lemma typing_helper_8[unfolded abbreviated_type_defs] : |
| "kinding [] (TRecord [(TPrim (Num U32), False), (TPrim (Num U32), False), (TFun abbreviatedType1 (TPrim (Num U32)), False), (TPrim (Num U32), False)] Unboxed) {E, S, D}" |
| apply (unfold abbreviated_type_defs)? |
| apply (tactic {* map (fn t => DETERM (interpret_tac t @{context} 1)) typing_helper_8_script |> EVERY *}) |
| done |
| |
| ML_quiet {* |
| val typing_helper_9_script : tac list = [ |
| (RTac @{thm kind_tfun[where k = "{E,S,D}"]}), |
| (RTac @{thm typing_helper_8}), |
| (RTac @{thm typing_helper_1}) |
| ] *} |
| |
| |
| lemma typing_helper_9[unfolded abbreviated_type_defs] : |
| "kinding [] (TFun (TRecord [(TPrim (Num U32), False), (TPrim (Num U32), False), (TFun abbreviatedType1 (TPrim (Num U32)), False), (TPrim (Num U32), False)] Unboxed) (TPrim (Num U32))) {E, S, D}" |
| apply (unfold abbreviated_type_defs)? |
| apply (tactic {* map (fn t => DETERM (interpret_tac t @{context} 1)) typing_helper_9_script |> EVERY *}) |
| done |
| |
| ML_quiet {* |
| val id_loopbody_typecorrect_script : hints list = [ |
| KindingTacs [(RTac @{thm typing_helper_2})], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_3})], |
| TypingTacs [], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_4})], |
| TypingTacs [], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_5})], |
| TypingTacs [(RTac @{thm typing_lit'}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_1},@{thm typing_helper_4}]),(SimpTac ([],[]))], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| TypingTacs [(RTac @{thm typing_cast}),(RTac @{thm typing_var}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_5}]),(SimpTac ([],[])),(SimpTac ([],[]))], |
| TypingTacs [] |
| ] *} |
| |
| |
| ML_quiet {* |
| val id_loopbody_ttyping_details_future = get_all_typing_details_future @{context} "id_loopbody" |
| id_loopbody_typecorrect_script*} |
| |
| |
| lemma id_loopbody_typecorrect : |
| "\<Xi>, fst id_loopbody_type, (id_loopbody_typetree, [Some (fst (snd id_loopbody_type))]) T\<turnstile> id_loopbody : snd (snd id_loopbody_type)" |
| apply (tactic {* resolve_future_typecorrect @{context} id_loopbody_ttyping_details_future *}) |
| done |
| |
| ML_quiet {* |
| val id_f_typecorrect_script : hints list = [ |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| TypingTacs [], |
| KindingTacs [(RTac @{thm typing_helper_5})], |
| TypingTacs [(RTac @{thm typing_lit'}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac []),(SimpTac ([],[]))], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| TypingTacs [(RTac @{thm typing_cast}),(RTac @{thm typing_var}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_5}]),(SimpTac ([],[])),(SimpTac ([],[]))], |
| KindingTacs [(RTac @{thm typing_helper_6})], |
| TypingTacs [(RTac @{thm typing_fun'}),(RTac @{thm id_loopbody_typecorrect[simplified id_loopbody_type_def id_loopbody_typetree_def abbreviated_type_defs, simplified]}),(RTac @{thm typing_helper_7}),(SimpTac ([],[])),(SimpTac ([],[])),(RTac @{thm exI[where x = "{E,S,D}"]}),(RTac @{thm typing_helper_2}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [])], |
| KindingTacs [(RTac @{thm typing_helper_5})], |
| TypingTacs [(RTac @{thm typing_lit'}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac []),(SimpTac ([],[]))], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| TypingTacs [(RTac @{thm typing_cast}),(RTac @{thm typing_var}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_5}]),(SimpTac ([],[])),(SimpTac ([],[]))], |
| KindingTacs [(RTac @{thm typing_helper_8})], |
| TypingTacs [], |
| TypingTacs [(RTac @{thm typing_app}),(SplitsTac (8,[(0,[(RTac @{thm split_comp.right}),(RTac @{thm typing_helper_8})])])),(RTac @{thm typing_afun'}),(SimpTac ([@{thm \<Xi>_def},@{thm seq32_0_type_def[unfolded abbreviated_type_defs]}],[])),(RTac @{thm typing_helper_7}),(SimpTac ([],[])),(SimpTac ([],[])),(RTac @{thm exI[where x = "{E,S,D}"]}),(RTac @{thm typing_helper_9}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac []),(RTac @{thm typing_var}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_8}]),(SimpTac ([],[]))] |
| ] *} |
| |
| |
| ML_quiet {* |
| val id_f_ttyping_details_future = get_all_typing_details_future @{context} "id_f" |
| id_f_typecorrect_script*} |
| |
| |
| lemma id_f_typecorrect : |
| "\<Xi>, fst id_f_type, (id_f_typetree, [Some (fst (snd id_f_type))]) T\<turnstile> id_f : snd (snd id_f_type)" |
| apply (tactic {* resolve_future_typecorrect @{context} id_f_ttyping_details_future *}) |
| done |
| |
| ML_quiet {* |
| val triangular_loopbody_typecorrect_script : hints list = [ |
| KindingTacs [(RTac @{thm typing_helper_2})], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_3})], |
| TypingTacs [], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_4})], |
| TypingTacs [], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| TypingTacs [(RTac @{thm typing_app}),(SplitsTac (5,[(0,[(RTac @{thm split_comp.right}),(RTac @{thm typing_helper_1})]),(1,[(RTac @{thm split_comp.left}),(RTac @{thm typing_helper_4})])])),(RTac @{thm typing_fun'}),(RTac @{thm id_f_typecorrect[simplified id_f_type_def id_f_typetree_def abbreviated_type_defs, simplified]}),(RTac @{thm typing_helper_7}),(SimpTac ([],[])),(SimpTac ([],[])),(RTac @{thm exI[where x = "{E,S,D}"]}),(RTac @{thm typing_helper_1}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_4}]),(RTac @{thm typing_var}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_1}]),(SimpTac ([],[]))], |
| TypingTacs [] |
| ] *} |
| |
| |
| ML_quiet {* |
| val triangular_loopbody_ttyping_details_future = get_all_typing_details_future @{context} "triangular_loopbody" |
| triangular_loopbody_typecorrect_script*} |
| |
| |
| lemma triangular_loopbody_typecorrect : |
| "\<Xi>, fst triangular_loopbody_type, (triangular_loopbody_typetree, [Some (fst (snd triangular_loopbody_type))]) T\<turnstile> triangular_loopbody : snd (snd triangular_loopbody_type)" |
| apply (tactic {* resolve_future_typecorrect @{context} triangular_loopbody_ttyping_details_future *}) |
| done |
| |
| ML_quiet {* |
| val triangular_typecorrect_script : hints list = [ |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| TypingTacs [], |
| KindingTacs [(RTac @{thm typing_helper_5})], |
| TypingTacs [(RTac @{thm typing_lit'}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac []),(SimpTac ([],[]))], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| TypingTacs [(RTac @{thm typing_cast}),(RTac @{thm typing_var}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_5}]),(SimpTac ([],[])),(SimpTac ([],[]))], |
| KindingTacs [(RTac @{thm typing_helper_6})], |
| TypingTacs [(RTac @{thm typing_fun'}),(RTac @{thm triangular_loopbody_typecorrect[simplified triangular_loopbody_type_def triangular_loopbody_typetree_def abbreviated_type_defs, simplified]}),(RTac @{thm typing_helper_7}),(SimpTac ([],[])),(SimpTac ([],[])),(RTac @{thm exI[where x = "{E,S,D}"]}),(RTac @{thm typing_helper_2}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [])], |
| KindingTacs [(RTac @{thm typing_helper_5})], |
| TypingTacs [(RTac @{thm typing_lit'}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac []),(SimpTac ([],[]))], |
| KindingTacs [(RTac @{thm typing_helper_1})], |
| TypingTacs [(RTac @{thm typing_cast}),(RTac @{thm typing_var}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_5}]),(SimpTac ([],[])),(SimpTac ([],[]))], |
| KindingTacs [(RTac @{thm typing_helper_8})], |
| TypingTacs [], |
| TypingTacs [(RTac @{thm typing_app}),(SplitsTac (8,[(0,[(RTac @{thm split_comp.right}),(RTac @{thm typing_helper_8})])])),(RTac @{thm typing_afun'}),(SimpTac ([@{thm \<Xi>_def},@{thm seq32_0_type_def[unfolded abbreviated_type_defs]}],[])),(RTac @{thm typing_helper_7}),(SimpTac ([],[])),(SimpTac ([],[])),(RTac @{thm exI[where x = "{E,S,D}"]}),(RTac @{thm typing_helper_9}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac []),(RTac @{thm typing_var}),(SimpTac ([@{thm empty_def}],[])),(WeakeningTac [@{thm typing_helper_8}]),(SimpTac ([],[]))] |
| ] *} |
| |
| |
| ML_quiet {* |
| val triangular_ttyping_details_future = get_all_typing_details_future @{context} "triangular" |
| triangular_typecorrect_script*} |
| |
| |
| lemma triangular_typecorrect : |
| "\<Xi>, fst triangular_type, (triangular_typetree, [Some (fst (snd triangular_type))]) T\<turnstile> triangular : snd (snd triangular_type)" |
| apply (tactic {* resolve_future_typecorrect @{context} triangular_ttyping_details_future *}) |
| done |
| |
| ML_quiet {* |
| val (_, id_loopbody_typing_tree, id_loopbody_typing_bucket) |
| = Future.join id_loopbody_ttyping_details_future |
| *} |
| |
| |
| ML_quiet {* |
| val (_, id_f_typing_tree, id_f_typing_bucket) |
| = Future.join id_f_ttyping_details_future |
| *} |
| |
| |
| ML_quiet {* |
| val (_, triangular_loopbody_typing_tree, triangular_loopbody_typing_bucket) |
| = Future.join triangular_loopbody_ttyping_details_future |
| *} |
| |
| |
| ML_quiet {* |
| val (_, triangular_typing_tree, triangular_typing_bucket) |
| = Future.join triangular_ttyping_details_future |
| *} |
| |
| |
| inductive seq32_0_sem where |
| "to \<ge> frm \<Longrightarrow> |
| seq32_0_sem \<xi> (\<sigma>, URecord [(UPrim (LU32 frm), r1), (UPrim (LU32 to), r2), |
| (UFunction loop_body [], r3), (acc, r4)]) |
| (\<sigma>, acc)" |
| | "\<lbrakk> to < frm; |
| seq32_0_sem \<xi> (\<sigma>, URecord [(UPrim (LU32 frm), r1), (UPrim (LU32 (to - 1)), r2), |
| (UFunction loop_body [], r4), (acc, r5)]) |
| (\<sigma>', acc'); |
| \<xi>, [UFunction loop_body [], URecord [(acc', r5), (UPrim (LU32 (to - 1)), r5)]] |
| \<turnstile> (\<sigma>', App (Var 0) (Var 1)) \<Down>! (\<sigma>'', acc'') \<rbrakk> \<Longrightarrow> |
| seq32_0_sem \<xi> (\<sigma>, URecord [(UPrim (LU32 frm), r1), (UPrim (LU32 to), r2), |
| (UFunction loop_body [], r4), (acc, r5)]) |
| (\<sigma>'', acc'')" |
| |
| |
| (* Parse C code *) |
| new_C_include_dir "../../cogent/lib" |
| new_C_include_dir "stdlib" |
| install_C_file "loopfull.c" |
| autocorres [ts_rules=nondet, no_opt, skip_word_abs] "loopfull.c" |
| (* *) |
| |
| (* C type and value relations *) |
| instantiation unit_t_C :: cogent_C_val begin |
| definition type_rel_unit_t_C_def: "type_rel r (_ :: unit_t_C itself) \<equiv> r = RUnit" |
| definition val_rel_unit_t_C_def: "val_rel uv (_ :: unit_t_C) \<equiv> uv = UUnit" |
| instance .. |
| end |
| |
| instantiation bool_t_C :: cogent_C_val |
| begin |
| definition type_rel_bool_t_C_def: |
| "type_rel typ (_ :: bool_t_C itself) \<equiv> (typ = RPrim Bool)" |
| definition val_rel_bool_t_C_def: |
| "val_rel uv (x :: bool_t_C) \<equiv> uv = UPrim (LBool (bool_t_C.boolean_C x \<noteq> 0))" |
| instance .. |
| end |
| |
| defs cogent_function_type_rel: |
| "cogent_function_type_rel typ x \<equiv> typ = RFun" |
| defs cogent_function_val_rel: |
| "cogent_function_val_rel uv x \<equiv> |
| (uv = UFunction id_loopbody [] \<and> x = sint FUN_ENUM_id_loopbody) \<or> |
| (uv = UFunction triangular_loopbody [] \<and> x = sint FUN_ENUM_triangular_loopbody)" |
| |
| |
| local_setup{* local_setup_val_rel_type_rel_put_them_in_buckets "loopfull.c" *} |
| |
| locale loop_proof = loopfull + update_sem_init |
| begin |
| |
| local_setup{* local_setup_take_put_member_case_esac_specialised_lemmas "loopfull.c" *} |
| |
| local_setup {* fold tidy_C_fun_def' Cogent_functions *} |
| |
| lemmas seq32_0'_def' = seq32_0'.simps |
| [simplified return_exn_simp, simplified guard_True_bind] |
| |
| lemmas dispatch_t2'_def' = dispatch_t2'.simps |
| [simplified return_exn_simp, simplified guard_True_bind] |
| |
| |
| |
| (* Specializations for dispatch_t2 *) |
| schematic_goal t2_dispatch_id_loopbody: |
| "\<lbrakk> tag = FUN_ENUM_id_loopbody; 0 < m \<rbrakk> \<Longrightarrow> |
| dispatch_t2' m tag args = id_loopbody' args" |
| by (monad_eq simp: dispatch_t2'_def') |
| |
| schematic_goal t2_dispatch_triangular_loopbody: |
| "\<lbrakk> tag = FUN_ENUM_triangular_loopbody; 0 < m \<rbrakk> \<Longrightarrow> |
| dispatch_t2' m tag args = triangular_loopbody' (recguard_dec m) args" |
| by (monad_eq simp: dispatch_t2'_def' FUN_ENUM_id_loopbody_def FUN_ENUM_triangular_loopbody_def) |
| |
| (* TODO: proof for abstract function *) |
| |
| definition \<xi>0 :: "(funtyp, abstyp, ptrtyp) uabsfuns" where "\<xi>0 fn \<equiv> undefined" |
| definition \<xi>1 :: "(funtyp, abstyp, ptrtyp) uabsfuns" where "\<xi>1 fn \<equiv> case fn of ''seq32_0'' \<Rightarrow> seq32_0_sem \<xi>0" |
| definition \<xi>2 :: "(funtyp, abstyp, ptrtyp) uabsfuns" where "\<xi>2 fn \<equiv> case fn of ''seq32_0'' \<Rightarrow> seq32_0_sem \<xi>1" |
| |
| lemma seq32_0_corres_0[simplified fst_conv snd_conv seq32_0_type_def id_loopbody_type_def abbreviated_type_defs]: |
| "\<lbrakk> 0 < m; |
| \<And>v v' \<sigma>' s'. val_rel v v' \<Longrightarrow> |
| corres srel |
| (App (Fun f []) (Var 0)) |
| (do ret \<leftarrow> dispatch_t2' (recguard_dec m) (t3_C.f_C a') v'; |
| gets (\<lambda>_. ret) od) |
| \<xi>0 (v # \<gamma>') \<Xi> (Some (fst (snd id_loopbody_type)) # \<Gamma>'') \<sigma>' s'; |
| val_rel a a'; |
| case a of URecord xs \<Rightarrow> fst (xs ! 2) = UFunction f [] |
| \<rbrakk> \<Longrightarrow> |
| corres srel |
| (App (AFun ''seq32_0'' []) (Var 0)) |
| (do ret \<leftarrow> seq32_0' m a'; gets (\<lambda>_. ret) od) |
| \<xi>1 (a # \<gamma>) \<Xi> (Some (fst (snd seq32_0_type)) # \<Gamma>') \<sigma> s" |
| apply (clarsimp simp: corres_def' seq32_0'_def') |
| |
| apply (rule validNF_bind[where B = "\<lambda>_ s0. s0 = s", rotated]) |
| apply (monad_eq simp: validNF_def valid_def no_fail_def) |
| apply (subst whileLoop_add_inv |
| [where M = "\<lambda>((_, i), _). t3_C.to_C a' - i" |
| and I = "\<lambda>(fargs, i) s. \<exists>\<sigma>' args. |
| (\<sigma>', s) \<in> srel \<and> |
| val_rel args (t3_C.to_C_update (\<lambda>_. i) a') \<and> |
| seq32_0_sem \<xi>1 (\<sigma>, args) (\<sigma>', UPrim (LU32 (t1_C.acc_C fargs)))"]) |
| apply wp |
| sorry |
| |
| lemma seq32_0_corres_1[simplified fst_conv snd_conv seq32_0_type_def id_loopbody_type_def abbreviated_type_defs]: |
| "\<lbrakk> 0 < m; |
| \<And>v v' \<sigma>' s'. val_rel v v' \<Longrightarrow> |
| corres srel |
| (App (Fun f []) (Var 0)) |
| (do ret \<leftarrow> dispatch_t2' (recguard_dec m) (t3_C.f_C a') v'; |
| gets (\<lambda>_. ret) od) |
| \<xi>1 (v # \<gamma>') \<Xi> (Some (fst (snd id_loopbody_type)) # \<Gamma>'') \<sigma>' s'; |
| val_rel a a'; |
| case a of URecord xs \<Rightarrow> fst (xs ! 2) = UFunction f [] |
| \<rbrakk> \<Longrightarrow> |
| corres srel |
| (App (AFun ''seq32_0'' []) (Var 0)) |
| (do ret \<leftarrow> seq32_0' m a'; gets (\<lambda>_. ret) od) |
| \<xi>2 (a # \<gamma>) \<Xi> (Some (fst (snd seq32_0_type)) # \<Gamma>') \<sigma> s" |
| sorry |
| |
| |
| (* Proofs *) |
| lemmas corres_nested_let = TrueI (* dummy for corres_tac *) |
| |
| lemma id_loopbody_corres[unfolded id_loopbody_type_def abbreviated_type_defs fst_conv snd_conv]: |
| "val_rel a a' \<Longrightarrow> corres srel id_loopbody (id_loopbody' a') \<xi>0 [a] \<Xi> [Some (fst (snd id_loopbody_type))] \<sigma> s" |
| apply (tactic {* corres_tac @{context} |
| (peel_two id_loopbody_typing_tree) |
| @{thms id_loopbody_def id_loopbody_type_def id_loopbody'_def' abbreviated_type_defs} |
| [] [] @{thm TrueI} [] |
| @{thms val_rel_word val_rel_fun_tag cogent_function_val_rel} |
| @{thms type_rel_word} |
| [] @{thm LETBANG_TRUE_def} @{thms list_to_map_more[where f=Var] list_to_map_singleton[where f=Var]} |
| true *}) |
| done |
| |
| lemma seq32_0_id_loopbody_corres[unfolded seq32_0_type_def abbreviated_type_defs fst_conv snd_conv]: |
| "\<lbrakk> m \<ge> 3; |
| val_rel a a'; |
| f_C a' = FUN_ENUM_id_loopbody |
| \<rbrakk> \<Longrightarrow> |
| corres srel |
| (App (AFun ''seq32_0'' []) (Var 0)) |
| (do ret \<leftarrow> seq32_0' (recguard_dec m) a'; gets (\<lambda>_. ret) od) |
| \<xi>1 (a # \<gamma>) \<Xi> |
| (Some (fst (snd seq32_0_type)) # \<Gamma>') \<sigma> s" |
| apply (unfold seq32_0_type_def abbreviated_type_defs fst_conv snd_conv) |
| apply (rule seq32_0_corres_0[where f=id_loopbody]) |
| apply (simp add: recguard_dec_def) |
| apply (simp add: dispatch_t2'_def') |
| apply (subst condition_true_pure) |
| apply (simp add: recguard_dec_def) |
| apply (subst unknown_bind_ignore) |
| apply (rule corres_u_sem_eq) |
| apply (rule u_sem_app) |
| apply (rule u_sem_fun) |
| apply (rule u_sem_var) |
| apply simp |
| apply (rule id_loopbody_corres) |
| apply simp |
| apply simp |
| apply (clarsimp simp: val_rel_t3_C_def val_rel_fun_tag cogent_function_val_rel |
| FUN_ENUM_id_loopbody_def FUN_ENUM_triangular_loopbody_def) |
| done |
| |
| lemma id_f_corres[unfolded id_f_type_def abbreviated_type_defs fst_conv snd_conv]: |
| "\<lbrakk> m \<ge> 3; val_rel a a' \<rbrakk> \<Longrightarrow> |
| corres srel id_f (id_f' m a') \<xi>1 [a] \<Xi> [Some (fst (snd id_f_type))] \<sigma> s" |
| apply (tactic {* corres_tac @{context} |
| (peel_two id_f_typing_tree) |
| @{thms id_f_def id_f_type_def id_f'_def' abbreviated_type_defs} |
| @{thms seq32_0_id_loopbody_corres} [] @{thm TrueI} [] |
| @{thms val_rel_word val_rel_fun_tag cogent_function_val_rel} |
| @{thms type_rel_word} |
| [] @{thm LETBANG_TRUE_def} @{thms list_to_map_more[where f=Var] list_to_map_singleton[where f=Var]} |
| true *}) |
| done |
| |
| lemma triangular_loopbody_corres[unfolded triangular_loopbody_type_def abbreviated_type_defs fst_conv snd_conv]: |
| "\<lbrakk> m \<ge> 4; val_rel a a' \<rbrakk> \<Longrightarrow> |
| corres srel triangular_loopbody (triangular_loopbody' m a') |
| \<xi>1 [a] \<Xi> [Some (fst (snd triangular_loopbody_type))] \<sigma> s" |
| apply (tactic {* corres_tac @{context} |
| (peel_two triangular_loopbody_typing_tree) |
| @{thms triangular_loopbody_def triangular_loopbody_type_def triangular_loopbody'_def' abbreviated_type_defs} |
| [] @{thms id_f_corres} @{thm TrueI} [] |
| @{thms val_rel_word val_rel_fun_tag cogent_function_val_rel} |
| @{thms type_rel_word} |
| [] @{thm LETBANG_TRUE_def} @{thms list_to_map_more[where f=Var] list_to_map_singleton[where f=Var]} |
| true *}) |
| done |
| |
| lemma seq32_0_triangular_loopbody_corres[unfolded seq32_0_type_def abbreviated_type_defs fst_conv snd_conv]: |
| "\<lbrakk> m \<ge> 7; val_rel a a'; f_C a' = FUN_ENUM_triangular_loopbody \<rbrakk> \<Longrightarrow> |
| corres srel |
| (App (AFun ''seq32_0'' []) (Var 0)) |
| (do ret \<leftarrow> seq32_0' (recguard_dec m) a'; gets (\<lambda>_. ret) od) |
| \<xi>2 (a # \<gamma>) \<Xi> |
| (Some (fst (snd seq32_0_type)) # \<Gamma>') \<sigma> s" |
| apply (unfold seq32_0_type_def abbreviated_type_defs fst_conv snd_conv) |
| apply (rule seq32_0_corres_1[where f=triangular_loopbody]) |
| apply (simp add: recguard_dec_def) |
| apply (simp add: dispatch_t2'_def') |
| apply (subst condition_false_pure) |
| apply (simp add: FUN_ENUM_id_loopbody_def FUN_ENUM_triangular_loopbody_def) |
| apply (subst unknown_bind_ignore) |
| apply (rule corres_u_sem_eq) |
| apply (rule u_sem_app) |
| apply (rule u_sem_fun) |
| apply (rule u_sem_var) |
| apply simp |
| apply (clarsimp simp: recguard_dec_def) |
| apply (rule triangular_loopbody_corres) |
| apply simp |
| apply simp |
| apply simp |
| apply (clarsimp simp: val_rel_t3_C_def val_rel_fun_tag cogent_function_val_rel |
| FUN_ENUM_id_loopbody_def FUN_ENUM_triangular_loopbody_def) |
| done |
| |
| lemma triangular_corres[unfolded triangular_type_def abbreviated_type_defs fst_conv snd_conv]: |
| "val_rel a a' \<Longrightarrow> corres srel triangular (triangular' a') \<xi>2 [a] \<Xi> [Some (fst (snd triangular_type))] \<sigma> s" |
| apply (tactic {* corres_tac @{context} |
| (peel_two triangular_typing_tree) |
| @{thms triangular_def triangular_type_def triangular'_def' abbreviated_type_defs} |
| @{thms seq32_0_triangular_loopbody_corres} [] @{thm TrueI} [] |
| @{thms val_rel_word val_rel_fun_tag cogent_function_val_rel} |
| @{thms type_rel_word} |
| [] @{thm LETBANG_TRUE_def} @{thms list_to_map_more[where f=Var] list_to_map_singleton[where f=Var]} |
| true *}) |
| done |
| |
| end |
| |
| |
| text {* Automatic proof of Cogent code, pushing abstract proof obligations into assumptions. *} |
| |
| context loop_proof begin |
| |
| lemmas [ValRelSimp] = val_rel_bool_t_C_def val_rel_unit_t_C_def val_rel_word val_rel_fun_tag cogent_function_val_rel |
| lemmas [TypeRelSimp] = type_rel_bool_t_C_def type_rel_unit_t_C_def type_rel_word type_rel_fun_tag |
| |
| definition "state_rel \<equiv> UNIV" |
| ML {* |
| fun corres_tac_local verbose ctxt |
| (typing_tree : thm Tree) |
| (fun_defs : thm list) |
| (absfun_corres : thm list) |
| (fun_corres : thm list) = |
| corres_tac ctxt |
| (typing_tree) |
| (fun_defs) |
| (absfun_corres) |
| (fun_corres) |
| @{thm TrueI} (* corres_if *) |
| @{thms corres_esacs} (* corres_esacs *) |
| @{thms untyped_func_enum_defs} |
| [] |
| @{thms TrueI} (* tag_enum_defs *) |
| @{thm LETBANG_TRUE_def} |
| @{thms list_to_map_more[where f=Var] |
| list_to_map_singleton[where f=Var]} |
| verbose; |
| *} |
| |
| ML {* |
| fun typing_tree_of "id_loopbody" = id_loopbody_typing_tree |
| | typing_tree_of "id_f" = id_f_typing_tree |
| | typing_tree_of "triangular_loopbody" = triangular_loopbody_typing_tree |
| | typing_tree_of "triangular" = triangular_typing_tree |
| | typing_tree_of f = error ("No typing tree for " ^ quote f) |
| *} |
| |
| ML {* |
| (* Categorise *) |
| val [(Cogent_functions_FO, Cogent_functions_HO), (Cogent_abstract_functions_FO, Cogent_abstract_functions_HO)] = |
| map (partition (get_Cogent_funtype @{context} #> Thm.prop_of #> Utils.rhs_of_eq #> funtype_is_first_order)) |
| [Cogent_functions, Cogent_abstract_functions]; |
| val _ = if null Cogent_functions_HO then () else |
| error ("Don't know how to handle higher-order Cogent functions: " ^ commas_quote Cogent_functions_HO); |
| *} |
| |
| ML {* |
| (* translate Cogent Invalue pointers to C record lookup terms *) |
| fun name_field ctxt (nm, funcs) = let |
| val nm' = case nm of Left f => f | Right f => f |
| val T = case Syntax.read_term ctxt (nm' ^ "'") of |
| Const (_, T) => T | t => raise TERM ("name_field: ", [t]) |
| val sourceT = domain_type T |
| (* Ignore measure (first parameter) for recursive C functions *) |
| val sourceT = if sourceT = @{typ nat} then domain_type (range_type T) else sourceT |
| fun typ_string T = dest_Type T |> fst |
| val source_var = Free ("x", sourceT) |
| fun access sourceT t [] = t |
| | access sourceT t (getter::getters) = let |
| val getterm = Syntax.read_term ctxt (typ_string sourceT ^ "." ^ getter) |
| val destT = range_type (type_of getterm) |
| in access destT (getterm $ t) getters end |
| in (nm, map (apfst (access sourceT source_var #> lambda source_var)) funcs) end |
| *} |
| |
| (* Higher-order function call annotations. *) |
| ML {* |
| val HO_call_hints = |
| Cogent_functions |
| |> Par_List.map (fn f => case CogentHigherOrder.make_HO_call_hints @{context} "loopfull.c" f of |
| [] => [] | hints => [(f, map (name_field @{context}) hints)]) |
| |> List.concat |
| |> Symtab.make |
| : ((string, string) Either * (term * (string, string) Either) list) list Symtab.table |
| *} |
| |
| ML {* |
| (* Sanity check HO_call_hints. *) |
| val _ = Symtab.dest HO_call_hints |> map (fn (f, calls) => ( |
| (if member (op =) Cogent_functions f then () else error ("HO_call_hints: no such function " ^ quote f)); |
| map (fn af => case af of Right _ => () | Left af => |
| if member (op =) Cogent_abstract_functions af then () else |
| error ("HO_call_hints: no such absfun " ^ quote af)) |
| (map fst calls); |
| map (fn af => case af of Right _ => () | Left af => |
| if member (op =) (Proof_Context.get_thm @{context} (f ^ "_def") |
| |> Thm.prop_of |> get_simple_function_calls) af then () |
| else error ("HO_call_hints: absfun " ^ quote af ^ " not in " ^ quote f)) (map fst calls) |
| (* TODO: check funargs and completeness *) |
| )) |
| *} |
| |
| ML {* |
| (* Abstract function names in the AST don't have theory prefixes *) |
| fun maybe_unprefix pre str = if String.isPrefix pre str then unprefix pre str else str |
| fun mapBoth f = mapEither f f |
| (* Entry point for verification *) |
| val Cogent_main_tree = |
| make_call_tree (Cogent_functions, Cogent_abstract_functions) |
| (Symtab.map (K (map (apsnd (map (apsnd (mapBoth (maybe_unprefix "Loop."))))))) HO_call_hints) @{context} |
| |> Symtab.map (K (annotate_depth #> annotate_measure)) |
| |
| val entry_funcs = Symtab.dest Cogent_main_tree |
| |> filter (fn (n, _) => member op= Cogent_functions n) |> Symtab.make |
| *} |
| |
| (* Define \<xi>_n. *) |
| ML {* |
| (* FIXME: actually merge trees for uabsfuns *) |
| val (deepest_tree::_) = |
| Symtab.dest Cogent_main_tree |> map snd |> filter (fn tr => |
| fst (CogentCallTree_data tr) = |
| (Symtab.dest Cogent_main_tree |> map snd |> map CogentCallTree_data |> map fst |> maximum)) |
| |> map (map_annotations fst) |
| *} |
| local_setup {* define_uabsfuns' deepest_tree *} |
| |
| (* Define corres theorems for all function calls under entry_funcs *) |
| ML {* val prop_tab = corres_tree_obligations entry_funcs @{context} *} |
| |
| (* Run proofs for generated functions *) |
| ML {* |
| val thm_tab = all_corres_goals (corres_tac_local false) typing_tree_of 42 @{context} prop_tab |
| *} |
| |
| (* Resolve function calls recursively *) |
| ML {* |
| val finalised_thms = |
| Symtab.dest thm_tab |
| |> Par_List.map (fn (n, maybe_thm) => |
| (n, Option.map (simp_xi @{context}) maybe_thm)) |
| |> Symtab.make |
| |> finalise prop_tab @{context} |
| *} |
| |
| (* Final theorem for entry point *) |
| ML {* Symtab.dest prop_tab |> filter (fn (_, p) => member (op=) (Symtab.keys entry_funcs) (#1 p)) |
| |> map (fn (thm, _) => @{trace} (thm, Symtab.lookup finalised_thms thm |> the |> the)) *} |
| |
| end |
| |
| end |