|
20319
|
1 |
(*
|
|
|
2 |
ID: $Id$
|
|
|
3 |
Author: Amine Chaieb, TU Muenchen
|
|
|
4 |
|
|
|
5 |
A trial for automatical reification.
|
|
|
6 |
*)
|
|
|
7 |
|
|
|
8 |
signature REFLECTION = sig
|
|
|
9 |
val genreify_tac: Proof.context -> thm list -> term option -> int -> tactic
|
|
|
10 |
val reflection_tac: Proof.context -> thm list -> term option -> int -> tactic
|
|
|
11 |
end;
|
|
|
12 |
|
|
|
13 |
structure Reflection : REFLECTION
|
|
|
14 |
= struct
|
|
|
15 |
|
|
|
16 |
(* Make a congruence rule out of a defining equation for the interpretation *)
|
|
|
17 |
(* th is one defining equation of f, i.e.
|
|
|
18 |
th is "f (Cp ?t1 ... ?tn) = P(f ?t1, .., f ?tn)" *)
|
|
|
19 |
(* Cp is a constructor pattern and P is a pattern *)
|
|
|
20 |
|
|
|
21 |
(* The result is:
|
|
|
22 |
[|?A1 = f ?t1 ; .. ; ?An= f ?tn |] ==> P (?A1, .., ?An) = f (Cp ?t1 .. ?tn) *)
|
|
|
23 |
(* + the a list of names of the A1 .. An, Those are fresh in the ctxt*)
|
|
|
24 |
|
|
|
25 |
fun mk_congeq ctxt fs th =
|
|
|
26 |
let
|
|
|
27 |
val Const(fname,fT)$(Free(_,_))$_ =
|
|
|
28 |
(fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of) th
|
|
|
29 |
val thy = ProofContext.theory_of ctxt;
|
|
|
30 |
val cert = Thm.cterm_of thy;
|
|
|
31 |
fun dest_listT (Type ("List.list",[vT])) = vT;
|
|
|
32 |
val vT = dest_listT (Term.domain_type fT);
|
|
|
33 |
val (((_,_),[th']), ctxt') = Variable.import true [th] ctxt;
|
|
|
34 |
val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop (Thm.prop_of th'));
|
|
|
35 |
|
|
|
36 |
fun add_fterms (t as t1 $ t2 $ t3) =
|
|
|
37 |
if exists (fn f => t1 aconv f) fs then insert (op aconv) t
|
|
|
38 |
else add_fterms (t1 $ t2) #> add_fterms t3
|
|
|
39 |
| add_fterms (t1 $ t2) = add_fterms t1 #> add_fterms t2
|
|
|
40 |
| add_fterms (Abs _) = sys_error "FIXME"
|
|
|
41 |
| add_fterms _ = I;
|
|
|
42 |
val fterms = add_fterms rhs [];
|
|
|
43 |
|
|
|
44 |
val (xs, ctxt'') = Variable.invent_fixes (replicate (length fterms) "x") ctxt';
|
|
|
45 |
val tys = map fastype_of fterms
|
|
|
46 |
val vs = map Free (xs ~~ tys);
|
|
|
47 |
val env = fterms ~~ vs;
|
|
|
48 |
|
|
|
49 |
fun replace_fterms (t as t1 $ t2 $ t3) =
|
|
|
50 |
(case AList.lookup (op aconv) env t of
|
|
|
51 |
SOME v => v
|
|
|
52 |
| NONE => replace_fterms (t1 $ t2) $ replace_fterms t3)
|
|
|
53 |
| replace_fterms (t1 $ t2) = replace_fterms t1 $ replace_fterms t2
|
|
|
54 |
| replace_fterms t = t;
|
|
|
55 |
|
|
|
56 |
fun mk_def (t, v) = HOLogic.mk_Trueprop (HOLogic.mk_eq (v, t));
|
|
|
57 |
val cong = (Goal.prove ctxt'' [] (map mk_def env)
|
|
|
58 |
(HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, replace_fterms rhs)))
|
|
|
59 |
(fn x => LocalDefs.unfold_tac (#context x) (#prems x) THEN rtac th' 1)) RS sym;
|
|
|
60 |
|
|
|
61 |
val (cong' :: vars') = Variable.export ctxt'' ctxt
|
|
|
62 |
(cong :: map (Drule.mk_term o cert) vs);
|
|
|
63 |
val vs' = map (fst o fst o Term.dest_Var o Thm.term_of o Drule.dest_term) vars';
|
|
|
64 |
in (vs', cong') end;
|
|
|
65 |
|
|
|
66 |
(* congs is a list of pairs (P,th) where th is a theorem for *)
|
|
|
67 |
(* [| f p1 = A1; ...; f pn = An|] ==> f (C p1 .. pn) = P *)
|
|
|
68 |
val FWD = curry (op OF);
|
|
|
69 |
|
|
|
70 |
(* da is the decomposition for atoms, ie. it returns ([],g) where g
|
|
|
71 |
returns the right instance f (AtC n) = t , where AtC is the Atoms
|
|
|
72 |
constructor and n is the number of the atom corresponding to t *)
|
|
|
73 |
|
|
|
74 |
(* Generic decomp for reification : matches the actual term with the
|
|
|
75 |
rhs of one cong rule. The result of the matching guides the
|
|
|
76 |
proof synthesis: The matches of the introduced Variables A1 .. An are
|
|
|
77 |
processed recursively
|
|
|
78 |
The rest is instantiated in the cong rule,i.e. no reification is needed *)
|
|
|
79 |
|
|
|
80 |
fun decomp_genreif thy da ((vns,cong)::congs) t =
|
|
|
81 |
((let
|
|
|
82 |
val cert = cterm_of thy
|
|
|
83 |
val (_, tmenv) =
|
|
|
84 |
Pattern.match thy
|
|
|
85 |
((fst o HOLogic.dest_eq o HOLogic.dest_Trueprop) (concl_of cong), t)
|
|
|
86 |
(Envir.type_env (Envir.empty 0),Term.Vartab.empty)
|
|
|
87 |
val (fnvs,invs) = List.partition (fn ((vn,_),_) => vn mem vns) (Vartab.dest tmenv)
|
|
|
88 |
val (fts,its) = (map (snd o snd) fnvs,
|
|
|
89 |
map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) invs)
|
|
|
90 |
in (fts, FWD (instantiate ([], its) cong))
|
|
|
91 |
end)
|
|
|
92 |
handle MATCH => decomp_genreif thy da congs t)
|
|
|
93 |
| decomp_genreif thy da [] t = da t;
|
|
|
94 |
|
|
|
95 |
(* We add the atoms here during reification *)
|
|
|
96 |
val env = ref ([]: (term list));
|
|
|
97 |
|
|
|
98 |
fun env_index t =
|
|
|
99 |
let val i = find_index_eq t (!env)
|
|
|
100 |
in if i = ~1 then (env:= (!env)@[t] ; (length (!env)) - 1) else i end;
|
|
|
101 |
|
|
|
102 |
exception REIF of string;
|
|
|
103 |
|
|
|
104 |
(* looks for the atoms equation and instantiates it with the right number *)
|
|
|
105 |
fun mk_decompatom thy eqs =
|
|
|
106 |
let fun isateq (_$_$(Const("List.nth",_)$_$_)) = true
|
|
|
107 |
| isateq _ = false
|
|
|
108 |
in case List.find (isateq o HOLogic.dest_Trueprop o prop_of) eqs of
|
|
|
109 |
NONE => raise REIF "Can not find the atoms equation"
|
|
|
110 |
| SOME th =>
|
|
|
111 |
fn t => ([],
|
|
|
112 |
fn ths =>
|
|
|
113 |
instantiate' [] [SOME(cterm_of thy (HOLogic.mk_nat(env_index t)))]
|
|
|
114 |
(th RS sym))
|
|
|
115 |
end;
|
|
|
116 |
|
|
|
117 |
(* Generic reification procedure: *)
|
|
|
118 |
(* creates all needed cong rules and then just uses the theorem synthesis *)
|
|
|
119 |
fun genreif ctxt raw_eqs t =
|
|
|
120 |
let val ([x], ctxt') = Variable.invent_fixes ["vs"] ctxt
|
|
|
121 |
val thy = ProofContext.theory_of ctxt'
|
|
|
122 |
val cert = cterm_of thy
|
|
|
123 |
val Const(fname,fT)$(Var(_,vT))$_ =
|
|
|
124 |
(fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of) (hd raw_eqs)
|
|
|
125 |
val cv = cert (Free(x, vT))
|
|
|
126 |
val eqs = map (instantiate' [] [SOME cv]) raw_eqs
|
|
|
127 |
val fs =
|
|
|
128 |
foldr (fn (eq,fns) =>
|
|
|
129 |
let val f$_$_ = (fst o HOLogic.dest_eq o
|
|
|
130 |
HOLogic.dest_Trueprop o prop_of) eq
|
|
|
131 |
in f ins fns end) [] eqs
|
|
|
132 |
val congs = map (mk_congeq ctxt' fs) eqs
|
|
|
133 |
val _ = (env := [])
|
|
|
134 |
val da = mk_decompatom thy eqs
|
|
|
135 |
val [th] = Variable.export ctxt' ctxt
|
|
|
136 |
[divide_and_conquer (decomp_genreif thy da congs) t]
|
|
|
137 |
val cv' = cterm_of (ProofContext.theory_of ctxt)
|
|
|
138 |
(HOLogic.mk_list I (body_type fT) (!env))
|
|
|
139 |
val _ = (env := [])
|
|
|
140 |
val th' = instantiate' [] [SOME cv'] th
|
|
|
141 |
val t' = (fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of) th'
|
|
|
142 |
val th'' = Goal.prove ctxt [] [] (HOLogic.mk_Trueprop (HOLogic.mk_eq (t, t')))
|
|
|
143 |
(fn _ => Simp_tac 1)
|
|
|
144 |
in FWD trans [th'',th']
|
|
|
145 |
end;
|
|
|
146 |
|
|
|
147 |
fun genreflect ctxt corr_thm raw_eqs t =
|
|
|
148 |
let val th = FWD trans [genreif ctxt raw_eqs t, corr_thm RS sym]
|
|
|
149 |
val ft = (snd o Thm.dest_comb o snd o Thm.dest_comb o snd o Thm.dest_comb o cprop_of) th
|
|
|
150 |
val rth = normalization_conv ft
|
|
|
151 |
in simplify (HOL_basic_ss addsimps raw_eqs addsimps [nth_Cons_0, nth_Cons_Suc])
|
|
|
152 |
(simplify (HOL_basic_ss addsimps [rth]) th)
|
|
|
153 |
end
|
|
|
154 |
|
|
|
155 |
fun genreify_tac ctxt eqs to i = (fn st =>
|
|
|
156 |
let
|
|
|
157 |
val P = HOLogic.dest_Trueprop (List.nth (prems_of st, i - 1))
|
|
|
158 |
val t = (case to of NONE => P | SOME x => x)
|
|
|
159 |
val th = (genreif ctxt eqs t) RS ssubst
|
|
|
160 |
in rtac th i st
|
|
|
161 |
end);
|
|
|
162 |
|
|
|
163 |
(* Reflection calls reification and uses the correctness *)
|
|
|
164 |
(* theorem assumed to be the dead of the list *)
|
|
|
165 |
fun reflection_tac ctxt (corr_thm::raw_eqs) to i =
|
|
|
166 |
(fn st =>
|
|
|
167 |
let val P = (HOLogic.dest_Trueprop (List.nth (prems_of st, i - 1)))
|
|
|
168 |
val t = (case to of NONE => P | SOME x => x)
|
|
|
169 |
val th = (genreflect ctxt corr_thm raw_eqs t) RS ssubst
|
|
|
170 |
in rtac th i st end);
|
|
|
171 |
|
|
|
172 |
end
|