| author | bulwahn | 
| Wed, 23 Sep 2009 16:20:12 +0200 | |
| changeset 32670 | cc0bae788b7e | 
| parent 32149 | ef59550a55d3 | 
| child 32960 | 69916a850301 | 
| permissions | -rw-r--r-- | 
| 29650 | 1  | 
(* Title: HOL/Library/reflection.ML  | 
2  | 
Author: Amine Chaieb, TU Muenchen  | 
|
| 20319 | 3  | 
|
4  | 
A trial for automatical reification.  | 
|
5  | 
*)  | 
|
6  | 
||
| 
29269
 
5c25a2012975
moved term order operations to structure TermOrd (cf. Pure/term_ord.ML);
 
wenzelm 
parents: 
24630 
diff
changeset
 | 
7  | 
signature REFLECTION =  | 
| 
 
5c25a2012975
moved term order operations to structure TermOrd (cf. Pure/term_ord.ML);
 
wenzelm 
parents: 
24630 
diff
changeset
 | 
8  | 
sig  | 
| 20319 | 9  | 
val genreify_tac: Proof.context -> thm list -> term option -> int -> tactic  | 
| 
23648
 
bccbf6138c30
Try several correctness theorems for reflection; rearrange cong rules to avoid the absoption cases;
 
chaieb 
parents: 
23643 
diff
changeset
 | 
10  | 
val reflection_tac: Proof.context -> thm list -> thm list -> term option -> int -> tactic  | 
| 21878 | 11  | 
val gen_reflection_tac: Proof.context -> (cterm -> thm)  | 
| 
23648
 
bccbf6138c30
Try several correctness theorems for reflection; rearrange cong rules to avoid the absoption cases;
 
chaieb 
parents: 
23643 
diff
changeset
 | 
12  | 
-> thm list -> thm list -> term option -> int -> tactic  | 
| 31810 | 13  | 
val genreif : Proof.context -> thm list -> term -> thm  | 
| 20319 | 14  | 
end;  | 
15  | 
||
| 
29269
 
5c25a2012975
moved term order operations to structure TermOrd (cf. Pure/term_ord.ML);
 
wenzelm 
parents: 
24630 
diff
changeset
 | 
16  | 
structure Reflection : REFLECTION =  | 
| 
 
5c25a2012975
moved term order operations to structure TermOrd (cf. Pure/term_ord.ML);
 
wenzelm 
parents: 
24630 
diff
changeset
 | 
17  | 
struct  | 
| 20319 | 18  | 
|
| 29650 | 19  | 
val ext2 = @{thm ext2};
 | 
20  | 
val nth_Cons_0 = @{thm nth_Cons_0};
 | 
|
21  | 
val nth_Cons_Suc = @{thm nth_Cons_Suc};
 | 
|
| 21669 | 22  | 
|
| 20374 | 23  | 
(* Make a congruence rule out of a defining equation for the interpretation *)  | 
24  | 
(* th is one defining equation of f, i.e.  | 
|
25  | 
th is "f (Cp ?t1 ... ?tn) = P(f ?t1, .., f ?tn)" *)  | 
|
26  | 
(* Cp is a constructor pattern and P is a pattern *)  | 
|
27  | 
||
28  | 
(* The result is:  | 
|
29  | 
[|?A1 = f ?t1 ; .. ; ?An= f ?tn |] ==> P (?A1, .., ?An) = f (Cp ?t1 .. ?tn) *)  | 
|
30  | 
(* + the a list of names of the A1 .. An, Those are fresh in the ctxt*)  | 
|
31  | 
||
| 31386 | 32  | 
fun mk_congeq ctxt fs th =  | 
33  | 
let  | 
|
34  | 
val (f as Const(fN,fT)) = th |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq  | 
|
| 29650 | 35  | 
|> fst |> strip_comb |> fst  | 
| 20374 | 36  | 
val thy = ProofContext.theory_of ctxt  | 
37  | 
val cert = Thm.cterm_of thy  | 
|
| 
31794
 
71af1fd6a5e4
renamed Variable.import_thms to Variable.import (back again cf. ed7aa5a350ef -- Alice is no longer supported);
 
wenzelm 
parents: 
31412 
diff
changeset
 | 
38  | 
val (((_,_),[th']), ctxt') = Variable.import true [th] ctxt  | 
| 20374 | 39  | 
val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop (Thm.prop_of th'))  | 
| 31386 | 40  | 
fun add_fterms (t as t1 $ t2) =  | 
| 
29269
 
5c25a2012975
moved term order operations to structure TermOrd (cf. Pure/term_ord.ML);
 
wenzelm 
parents: 
24630 
diff
changeset
 | 
41  | 
if exists (fn f => Term.could_unify (t |> strip_comb |> fst, f)) fs then insert (op aconv) t  | 
| 
20564
 
6857bd9f1a79
Reifiaction now deals with Interpretations with an arbtrary number of parameters. It deals with binding. The Atomic cases can be I ... = f (xs!n)
 
chaieb 
parents: 
20374 
diff
changeset
 | 
42  | 
else add_fterms t1 #> add_fterms t2  | 
| 31386 | 43  | 
| add_fterms (t as Abs(xn,xT,t')) =  | 
| 29273 | 44  | 
if exists_Const (fn (c, _) => c = fN) t then (fn _ => [t]) else (fn _ => [])  | 
| 20374 | 45  | 
| add_fterms _ = I  | 
46  | 
val fterms = add_fterms rhs []  | 
|
| 
20797
 
c1f0bc7e7d80
renamed Variable.invent_fixes to Variable.variant_fixes;
 
wenzelm 
parents: 
20595 
diff
changeset
 | 
47  | 
val (xs, ctxt'') = Variable.variant_fixes (replicate (length fterms) "x") ctxt'  | 
| 20374 | 48  | 
val tys = map fastype_of fterms  | 
49  | 
val vs = map Free (xs ~~ tys)  | 
|
50  | 
val env = fterms ~~ vs  | 
|
| 31386 | 51  | 
(* FIXME!!!!*)  | 
| 
20564
 
6857bd9f1a79
Reifiaction now deals with Interpretations with an arbtrary number of parameters. It deals with binding. The Atomic cases can be I ... = f (xs!n)
 
chaieb 
parents: 
20374 
diff
changeset
 | 
52  | 
fun replace_fterms (t as t1 $ t2) =  | 
| 20374 | 53  | 
(case AList.lookup (op aconv) env t of  | 
54  | 
SOME v => v  | 
|
| 
20564
 
6857bd9f1a79
Reifiaction now deals with Interpretations with an arbtrary number of parameters. It deals with binding. The Atomic cases can be I ... = f (xs!n)
 
chaieb 
parents: 
20374 
diff
changeset
 | 
55  | 
| NONE => replace_fterms t1 $ replace_fterms t2)  | 
| 20374 | 56  | 
| replace_fterms t = (case AList.lookup (op aconv) env t of  | 
57  | 
SOME v => v  | 
|
58  | 
| NONE => t)  | 
|
| 31386 | 59  | 
|
| 20374 | 60  | 
fun mk_def (Abs(x,xT,t),v) = HOLogic.mk_Trueprop ((HOLogic.all_const xT)$ Abs(x,xT,HOLogic.mk_eq(v$(Bound 0), t)))  | 
61  | 
| mk_def (t, v) = HOLogic.mk_Trueprop (HOLogic.mk_eq (v, t))  | 
|
| 23605 | 62  | 
fun tryext x = (x RS ext2 handle THM _ => x)  | 
| 20374 | 63  | 
val cong = (Goal.prove ctxt'' [] (map mk_def env)  | 
64  | 
(HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, replace_fterms rhs)))  | 
|
| 31386 | 65  | 
(fn x => LocalDefs.unfold_tac (#context x) (map tryext (#prems x))  | 
| 20374 | 66  | 
THEN rtac th' 1)) RS sym  | 
| 31386 | 67  | 
|
68  | 
val (cong' :: vars') =  | 
|
| 20374 | 69  | 
Variable.export ctxt'' ctxt (cong :: map (Drule.mk_term o cert) vs)  | 
70  | 
val vs' = map (fst o fst o Term.dest_Var o Thm.term_of o Drule.dest_term) vars'  | 
|
| 31386 | 71  | 
|
72  | 
in (vs', cong') end;  | 
|
| 20319 | 73  | 
(* congs is a list of pairs (P,th) where th is a theorem for *)  | 
74  | 
(* [| f p1 = A1; ...; f pn = An|] ==> f (C p1 .. pn) = P *)  | 
|
75  | 
val FWD = curry (op OF);  | 
|
76  | 
||
77  | 
||
| 20374 | 78  | 
exception REIF of string;  | 
79  | 
||
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
80  | 
fun dest_listT (Type (@{type_name "list"}, [T])) = T;
 | 
| 29834 | 81  | 
|
| 31387 | 82  | 
(* This modified version of divide_and_conquer allows the threading  | 
83  | 
of a state variable *)  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
84  | 
fun divide_and_conquer' decomp s x =  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
85  | 
let val ((ys, recomb), s') = decomp s x  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
86  | 
in recomb (fold_map (divide_and_conquer' decomp) ys s') end;  | 
| 31387 | 87  | 
|
| 31386 | 88  | 
fun rearrange congs =  | 
89  | 
let  | 
|
90  | 
fun P (_, th) =  | 
|
91  | 
      let val @{term "Trueprop"}$(Const ("op =",_) $l$_) = concl_of th
 | 
|
92  | 
in can dest_Var l end  | 
|
93  | 
val (yes,no) = List.partition P congs  | 
|
94  | 
in no @ yes end  | 
|
| 29834 | 95  | 
|
96  | 
fun genreif ctxt raw_eqs t =  | 
|
| 31386 | 97  | 
let  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
98  | 
fun index_of t bds =  | 
| 31386 | 99  | 
let  | 
100  | 
val tt = HOLogic.listT (fastype_of t)  | 
|
101  | 
in  | 
|
| 31387 | 102  | 
(case AList.lookup Type.could_unify bds tt of  | 
| 31386 | 103  | 
NONE => error "index_of : type not found in environements!"  | 
104  | 
| SOME (tbs,tats) =>  | 
|
105  | 
let  | 
|
| 31986 | 106  | 
val i = find_index (fn t' => t' = t) tats  | 
107  | 
val j = find_index (fn t' => t' = t) tbs  | 
|
| 31387 | 108  | 
in (if j = ~1 then  | 
109  | 
if i = ~1  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
110  | 
then (length tbs + length tats,  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
111  | 
AList.update Type.could_unify (tt,(tbs,tats@[t])) bds)  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
112  | 
else (i, bds) else (j, bds))  | 
| 31386 | 113  | 
end)  | 
114  | 
end;  | 
|
115  | 
||
116  | 
(* Generic decomp for reification : matches the actual term with the  | 
|
117  | 
rhs of one cong rule. The result of the matching guides the  | 
|
118  | 
proof synthesis: The matches of the introduced Variables A1 .. An are  | 
|
119  | 
processed recursively  | 
|
120  | 
The rest is instantiated in the cong rule,i.e. no reification is needed *)  | 
|
| 
20564
 
6857bd9f1a79
Reifiaction now deals with Interpretations with an arbtrary number of parameters. It deals with binding. The Atomic cases can be I ... = f (xs!n)
 
chaieb 
parents: 
20374 
diff
changeset
 | 
121  | 
|
| 31386 | 122  | 
(* da is the decomposition for atoms, ie. it returns ([],g) where g  | 
123  | 
returns the right instance f (AtC n) = t , where AtC is the Atoms  | 
|
124  | 
constructor and n is the number of the atom corresponding to t *)  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
125  | 
fun decomp_genreif da cgns (t,ctxt) bds =  | 
| 31386 | 126  | 
let  | 
127  | 
val thy = ProofContext.theory_of ctxt  | 
|
| 20374 | 128  | 
val cert = cterm_of thy  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
129  | 
fun tryabsdecomp (s,ctxt) bds =  | 
| 31386 | 130  | 
(case s of  | 
131  | 
Abs(xn,xT,ta) => (  | 
|
132  | 
let  | 
|
133  | 
val ([xn],ctxt') = Variable.variant_fixes ["x"] ctxt  | 
|
134  | 
val (xn,ta) = variant_abs (xn,xT,ta)  | 
|
135  | 
val x = Free(xn,xT)  | 
|
| 31387 | 136  | 
val bds = (case AList.lookup Type.could_unify bds (HOLogic.listT xT)  | 
| 31386 | 137  | 
of NONE => error "tryabsdecomp: Type not found in the Environement"  | 
138  | 
| SOME (bsT,atsT) =>  | 
|
| 31387 | 139  | 
(AList.update Type.could_unify (HOLogic.listT xT, ((x::bsT), atsT)) bds))  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
140  | 
in (([(ta, ctxt')],  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
141  | 
fn ([th], bds) =>  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
142  | 
(hd (Variable.export ctxt' ctxt [(forall_intr (cert x) th) COMP allI]),  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
143  | 
let val (bsT,asT) = the(AList.lookup Type.could_unify bds (HOLogic.listT xT))  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
144  | 
in AList.update Type.could_unify (HOLogic.listT xT,(tl bsT,asT)) bds  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
145  | 
end)),  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
146  | 
bds)  | 
| 31386 | 147  | 
end)  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
148  | 
| _ => da (s,ctxt) bds)  | 
| 31386 | 149  | 
in (case cgns of  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
150  | 
[] => tryabsdecomp (t,ctxt) bds  | 
| 31386 | 151  | 
| ((vns,cong)::congs) => ((let  | 
152  | 
val cert = cterm_of thy  | 
|
153  | 
val certy = ctyp_of thy  | 
|
154  | 
val (tyenv, tmenv) =  | 
|
155  | 
Pattern.match thy  | 
|
| 32032 | 156  | 
((fst o HOLogic.dest_eq o HOLogic.dest_Trueprop) (concl_of cong), t)  | 
157  | 
(Vartab.empty, Vartab.empty)  | 
|
| 31386 | 158  | 
val (fnvs,invs) = List.partition (fn ((vn,_),_) => vn mem vns) (Vartab.dest tmenv)  | 
159  | 
val (fts,its) =  | 
|
160  | 
(map (snd o snd) fnvs,  | 
|
161  | 
map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) invs)  | 
|
162  | 
val ctyenv = map (fn ((vn,vi),(s,ty)) => (certy (TVar((vn,vi),s)), certy ty)) (Vartab.dest tyenv)  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
163  | 
in ((fts ~~ (replicate (length fts) ctxt),  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
164  | 
Library.apfst (FWD (instantiate (ctyenv, its) cong))), bds)  | 
| 31386 | 165  | 
end)  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
166  | 
handle MATCH => decomp_genreif da congs (t,ctxt) bds))  | 
| 31386 | 167  | 
end;  | 
| 
23648
 
bccbf6138c30
Try several correctness theorems for reflection; rearrange cong rules to avoid the absoption cases;
 
chaieb 
parents: 
23643 
diff
changeset
 | 
168  | 
|
| 
 
bccbf6138c30
Try several correctness theorems for reflection; rearrange cong rules to avoid the absoption cases;
 
chaieb 
parents: 
23643 
diff
changeset
 | 
169  | 
(* looks for the atoms equation and instantiates it with the right number *)  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
170  | 
fun mk_decompatom eqs (t,ctxt) bds = (([], fn (_, bds) =>  | 
| 31386 | 171  | 
let  | 
172  | 
val tT = fastype_of t  | 
|
173  | 
fun isat eq =  | 
|
174  | 
let  | 
|
175  | 
val rhs = eq |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd  | 
|
176  | 
in exists_Const  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
177  | 
	    (fn (n,ty) => n = @{const_name "List.nth"}
 | 
| 31386 | 178  | 
andalso  | 
| 31387 | 179  | 
AList.defined Type.could_unify bds (domain_type ty)) rhs  | 
| 31386 | 180  | 
andalso Type.could_unify (fastype_of rhs, tT)  | 
181  | 
end  | 
|
182  | 
||
183  | 
fun get_nths t acc =  | 
|
184  | 
case t of  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
185  | 
            Const(@{const_name "List.nth"},_)$vs$n => insert (fn ((a,_),(b,_)) => a aconv b) (t,(vs,n)) acc
 | 
| 31386 | 186  | 
| t1$t2 => get_nths t1 (get_nths t2 acc)  | 
187  | 
| Abs(_,_,t') => get_nths t' acc  | 
|
188  | 
| _ => acc  | 
|
| 
23548
 
e25991f126ce
Generalized case for atoms. Selection of environment lists is allowed more than once.
 
chaieb 
parents: 
22568 
diff
changeset
 | 
189  | 
|
| 31386 | 190  | 
fun  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
191  | 
tryeqs [] bds = error "Can not find the atoms equation"  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
192  | 
| tryeqs (eq::eqs) bds = ((  | 
| 31386 | 193  | 
let  | 
194  | 
val rhs = eq |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd  | 
|
195  | 
val nths = get_nths rhs []  | 
|
196  | 
val (vss,ns) = fold_rev (fn (_,(vs,n)) => fn (vss,ns) =>  | 
|
197  | 
(insert (op aconv) vs vss, insert (op aconv) n ns)) nths ([],[])  | 
|
198  | 
val (vsns, ctxt') = Variable.variant_fixes (replicate (length vss) "vs") ctxt  | 
|
199  | 
val (xns, ctxt'') = Variable.variant_fixes (replicate (length nths) "x") ctxt'  | 
|
200  | 
val thy = ProofContext.theory_of ctxt''  | 
|
201  | 
val cert = cterm_of thy  | 
|
202  | 
val certT = ctyp_of thy  | 
|
203  | 
val vsns_map = vss ~~ vsns  | 
|
204  | 
val xns_map = (fst (split_list nths)) ~~ xns  | 
|
205  | 
val subst = map (fn (nt, xn) => (nt, Var ((xn,0), fastype_of nt))) xns_map  | 
|
206  | 
val rhs_P = subst_free subst rhs  | 
|
| 32032 | 207  | 
val (tyenv, tmenv) = Pattern.match thy (rhs_P, t) (Vartab.empty, Vartab.empty)  | 
| 32035 | 208  | 
val sbst = Envir.subst_term (tyenv, tmenv)  | 
209  | 
val sbsT = Envir.subst_type tyenv  | 
|
| 31386 | 210  | 
val subst_ty = map (fn (n,(s,t)) => (certT (TVar (n, s)), certT t))  | 
211  | 
(Vartab.dest tyenv)  | 
|
212  | 
val tml = Vartab.dest tmenv  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
213  | 
val t's = map (fn xn => snd (the (AList.lookup (op =) tml (xn,0)))) xns (* FIXME : Express with sbst*)  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
214  | 
val (subst_ns, bds) = fold_map  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
215  | 
(fn (Const _ $ vs $ n, Var (xn0,T)) => fn bds =>  | 
| 31387 | 216  | 
let  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
217  | 
val name = snd (the (AList.lookup (op =) tml xn0))  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
218  | 
val (idx, bds) = index_of name bds  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
219  | 
in ((cert n, idx |> (HOLogic.mk_nat #> cert)), bds) end) subst bds  | 
| 31386 | 220  | 
val subst_vs =  | 
221  | 
let  | 
|
222  | 
fun ty (Const _ $ (vs as Var (vsn,lT)) $ n, Var (xn0,T)) = (certT T, certT (sbsT T))  | 
|
223  | 
fun h (Const _ $ (vs as Var (vsn,lT)) $ n, Var (xn0,T)) =  | 
|
224  | 
let  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
225  | 
                    val cns = sbst (Const(@{const_name "List.Cons"}, T --> lT --> lT))
 | 
| 31386 | 226  | 
val lT' = sbsT lT  | 
| 31387 | 227  | 
val (bsT,asT) = the (AList.lookup Type.could_unify bds lT)  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
228  | 
val vsn = the (AList.lookup (op =) vsns_map vs)  | 
| 31386 | 229  | 
val cvs = cert (fold_rev (fn x => fn xs => cns$x$xs) bsT (Free (vsn, lT')))  | 
230  | 
in (cert vs, cvs) end  | 
|
231  | 
in map h subst end  | 
|
232  | 
val cts = map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t))  | 
|
233  | 
(fold (AList.delete (fn (((a: string),_),(b,_)) => a = b))  | 
|
234  | 
(map (fn n => (n,0)) xns) tml)  | 
|
235  | 
val substt =  | 
|
236  | 
let val ih = Drule.cterm_rule (Thm.instantiate (subst_ty,[]))  | 
|
237  | 
in map (fn (v,t) => (ih v, ih t)) (subst_ns@subst_vs@cts) end  | 
|
238  | 
val th = (instantiate (subst_ty, substt) eq) RS sym  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
239  | 
in (hd (Variable.export ctxt'' ctxt [th]), bds) end)  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
240  | 
handle MATCH => tryeqs eqs bds)  | 
| 
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
241  | 
in tryeqs (filter isat eqs) bds end), bds);  | 
| 20374 | 242  | 
|
| 20319 | 243  | 
(* Generic reification procedure: *)  | 
244  | 
(* creates all needed cong rules and then just uses the theorem synthesis *)  | 
|
| 
20564
 
6857bd9f1a79
Reifiaction now deals with Interpretations with an arbtrary number of parameters. It deals with binding. The Atomic cases can be I ... = f (xs!n)
 
chaieb 
parents: 
20374 
diff
changeset
 | 
245  | 
|
| 31386 | 246  | 
fun mk_congs ctxt raw_eqs =  | 
247  | 
let  | 
|
248  | 
val fs = fold_rev (fn eq =>  | 
|
249  | 
insert (op =) (eq |> prop_of |> HOLogic.dest_Trueprop  | 
|
250  | 
|> HOLogic.dest_eq |> fst |> strip_comb  | 
|
251  | 
|> fst)) raw_eqs []  | 
|
252  | 
val tys = fold_rev (fn f => fold (insert (op =)) (f |> fastype_of |> binder_types |> tl)  | 
|
253  | 
) fs []  | 
|
254  | 
val (vs, ctxt') = Variable.variant_fixes (replicate (length tys) "vs") ctxt  | 
|
255  | 
val thy = ProofContext.theory_of ctxt'  | 
|
256  | 
val cert = cterm_of thy  | 
|
257  | 
val vstys = map (fn (t,v) => (t,SOME (cert (Free(v,t)))))  | 
|
258  | 
(tys ~~ vs)  | 
|
259  | 
val is_Var = can dest_Var  | 
|
260  | 
fun insteq eq vs =  | 
|
261  | 
let  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
262  | 
val subst = map (fn (v as Var(n,t)) => (cert v, (the o the) (AList.lookup (op =) vstys t)))  | 
| 31386 | 263  | 
(filter is_Var vs)  | 
264  | 
in Thm.instantiate ([],subst) eq  | 
|
265  | 
end  | 
|
| 
20564
 
6857bd9f1a79
Reifiaction now deals with Interpretations with an arbtrary number of parameters. It deals with binding. The Atomic cases can be I ... = f (xs!n)
 
chaieb 
parents: 
20374 
diff
changeset
 | 
266  | 
|
| 31387 | 267  | 
val bds = AList.make (fn _ => ([],[])) tys  | 
| 31386 | 268  | 
val eqs = map (fn eq => eq |> prop_of |> HOLogic.dest_Trueprop  | 
269  | 
|> HOLogic.dest_eq |> fst |> strip_comb |> snd |> tl  | 
|
270  | 
|> (insteq eq)) raw_eqs  | 
|
271  | 
val (ps,congs) = split_list (map (mk_congeq ctxt' fs) eqs)  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
272  | 
in (ps ~~ (Variable.export ctxt' ctxt congs), bds)  | 
| 31386 | 273  | 
end  | 
274  | 
||
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
275  | 
val (congs, bds) = mk_congs ctxt raw_eqs  | 
| 31387 | 276  | 
val congs = rearrange congs  | 
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
277  | 
val (th, bds) = divide_and_conquer' (decomp_genreif (mk_decompatom raw_eqs) congs) (t,ctxt) bds  | 
| 31386 | 278  | 
fun is_listVar (Var (_,t)) = can dest_listT t  | 
279  | 
| is_listVar _ = false  | 
|
280  | 
val vars = th |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd  | 
|
281  | 
|> strip_comb |> snd |> filter is_listVar  | 
|
282  | 
val cert = cterm_of (ProofContext.theory_of ctxt)  | 
|
283  | 
val cvs = map (fn (v as Var(n,t)) => (cert v,  | 
|
| 31387 | 284  | 
the (AList.lookup Type.could_unify bds t) |> snd |> HOLogic.mk_list (dest_listT t) |> cert)) vars  | 
| 31386 | 285  | 
val th' = instantiate ([], cvs) th  | 
286  | 
val t' = (fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of) th'  | 
|
287  | 
val th'' = Goal.prove ctxt [] [] (HOLogic.mk_Trueprop (HOLogic.mk_eq (t, t')))  | 
|
| 
32149
 
ef59550a55d3
renamed simpset_of to global_simpset_of, and local_simpset_of to simpset_of -- same for claset and clasimpset;
 
wenzelm 
parents: 
32035 
diff
changeset
 | 
288  | 
(fn _ => simp_tac (simpset_of ctxt) 1)  | 
| 31386 | 289  | 
in FWD trans [th'',th']  | 
290  | 
end  | 
|
| 20319 | 291  | 
|
| 
23648
 
bccbf6138c30
Try several correctness theorems for reflection; rearrange cong rules to avoid the absoption cases;
 
chaieb 
parents: 
23643 
diff
changeset
 | 
292  | 
|
| 
 
bccbf6138c30
Try several correctness theorems for reflection; rearrange cong rules to avoid the absoption cases;
 
chaieb 
parents: 
23643 
diff
changeset
 | 
293  | 
fun genreflect ctxt conv corr_thms raw_eqs t =  | 
| 31386 | 294  | 
let  | 
295  | 
val reifth = genreif ctxt raw_eqs t  | 
|
296  | 
fun trytrans [] = error "No suitable correctness theorem found"  | 
|
297  | 
| trytrans (th::ths) =  | 
|
298  | 
(FWD trans [reifth, th RS sym] handle THM _ => trytrans ths)  | 
|
299  | 
val th = trytrans corr_thms  | 
|
300  | 
val ft = (Thm.dest_arg1 o Thm.dest_arg o Thm.dest_arg o cprop_of) th  | 
|
301  | 
val rth = conv ft  | 
|
302  | 
in simplify (HOL_basic_ss addsimps raw_eqs addsimps [nth_Cons_0, nth_Cons_Suc])  | 
|
303  | 
(simplify (HOL_basic_ss addsimps [rth]) th)  | 
|
304  | 
end  | 
|
| 20319 | 305  | 
|
306  | 
fun genreify_tac ctxt eqs to i = (fn st =>  | 
|
307  | 
let  | 
|
| 
31412
 
f2e6b6526092
Converted reification to use fold_map instead of Library.foldl_map. Use antiquotations.
 
hoelzl 
parents: 
31387 
diff
changeset
 | 
308  | 
fun P () = HOLogic.dest_Trueprop (nth (prems_of st) (i - 1))  | 
| 29805 | 309  | 
val t = (case to of NONE => P () | SOME x => x)  | 
| 20319 | 310  | 
val th = (genreif ctxt eqs t) RS ssubst  | 
311  | 
in rtac th i st  | 
|
312  | 
end);  | 
|
313  | 
||
314  | 
(* Reflection calls reification and uses the correctness *)  | 
|
315  | 
(* theorem assumed to be the dead of the list *)  | 
|
| 
23648
 
bccbf6138c30
Try several correctness theorems for reflection; rearrange cong rules to avoid the absoption cases;
 
chaieb 
parents: 
23643 
diff
changeset
 | 
316  | 
fun gen_reflection_tac ctxt conv corr_thms raw_eqs to i = (fn st =>  | 
| 21878 | 317  | 
let  | 
318  | 
val P = HOLogic.dest_Trueprop (nth (prems_of st) (i - 1));  | 
|
319  | 
val t = the_default P to;  | 
|
| 
23648
 
bccbf6138c30
Try several correctness theorems for reflection; rearrange cong rules to avoid the absoption cases;
 
chaieb 
parents: 
23643 
diff
changeset
 | 
320  | 
val th = genreflect ctxt conv corr_thms raw_eqs t  | 
| 21878 | 321  | 
RS ssubst;  | 
| 23791 | 322  | 
in (rtac th i THEN TRY(rtac TrueI i)) st end);  | 
| 21878 | 323  | 
|
| 23791 | 324  | 
fun reflection_tac ctxt = gen_reflection_tac ctxt Codegen.evaluation_conv;  | 
| 30969 | 325  | 
(*FIXME why Codegen.evaluation_conv? very specific...*)  | 
| 29650 | 326  | 
|
| 
20797
 
c1f0bc7e7d80
renamed Variable.invent_fixes to Variable.variant_fixes;
 
wenzelm 
parents: 
20595 
diff
changeset
 | 
327  | 
end  |