blob: ff7902d4fe3df4aeac94bc4a0ba2e39d67a84ac4 [file] [log] [blame] [edit]
(*
* 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