27 (* The result is: |
27 (* The result is: |
28 [|?A1 = f ?t1 ; .. ; ?An= f ?tn |] ==> P (?A1, .., ?An) = f (Cp ?t1 .. ?tn) *) |
28 [|?A1 = f ?t1 ; .. ; ?An= f ?tn |] ==> P (?A1, .., ?An) = f (Cp ?t1 .. ?tn) *) |
29 (* + the a list of names of the A1 .. An, Those are fresh in the ctxt*) |
29 (* + the a list of names of the A1 .. An, Those are fresh in the ctxt*) |
30 |
30 |
31 |
31 |
32 fun mk_congeq ctxt fs th = |
32 fun mk_congeq ctxt fs th = |
33 let |
33 let |
34 val (f as Const(fN,fT)) = th |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |
34 val (f as Const(fN,fT)) = th |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |
35 |> fst |> strip_comb |> fst |
35 |> fst |> strip_comb |> fst |
36 val thy = ProofContext.theory_of ctxt |
36 val thy = ProofContext.theory_of ctxt |
37 val cert = Thm.cterm_of thy |
37 val cert = Thm.cterm_of thy |
38 val (((_,_),[th']), ctxt') = Variable.import_thms true [th] ctxt |
38 val (((_,_),[th']), ctxt') = Variable.import_thms true [th] ctxt |
39 val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop (Thm.prop_of th')) |
39 val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop (Thm.prop_of th')) |
40 fun add_fterms (t as t1 $ t2) = |
40 fun add_fterms (t as t1 $ t2) = |
41 if exists (fn f => Term.could_unify (t |> strip_comb |> fst, f)) fs then insert (op aconv) t |
41 if exists (fn f => Term.could_unify (t |> strip_comb |> fst, f)) fs then insert (op aconv) t |
42 else add_fterms t1 #> add_fterms t2 |
42 else add_fterms t1 #> add_fterms t2 |
43 | add_fterms (t as Abs(xn,xT,t')) = |
43 | add_fterms (t as Abs(xn,xT,t')) = |
44 if exists_Const (fn (c, _) => c = fN) t then (fn _ => [t]) else (fn _ => []) |
44 if exists_Const (fn (c, _) => c = fN) t then (fn _ => [t]) else (fn _ => []) |
45 | add_fterms _ = I |
45 | add_fterms _ = I |
46 val fterms = add_fterms rhs [] |
46 val fterms = add_fterms rhs [] |
47 val (xs, ctxt'') = Variable.variant_fixes (replicate (length fterms) "x") ctxt' |
47 val (xs, ctxt'') = Variable.variant_fixes (replicate (length fterms) "x") ctxt' |
48 val tys = map fastype_of fterms |
48 val tys = map fastype_of fterms |
49 val vs = map Free (xs ~~ tys) |
49 val vs = map Free (xs ~~ tys) |
50 val env = fterms ~~ vs |
50 val env = fterms ~~ vs |
51 (* FIXME!!!!*) |
51 (* FIXME!!!!*) |
52 fun replace_fterms (t as t1 $ t2) = |
52 fun replace_fterms (t as t1 $ t2) = |
53 (case AList.lookup (op aconv) env t of |
53 (case AList.lookup (op aconv) env t of |
54 SOME v => v |
54 SOME v => v |
55 | NONE => replace_fterms t1 $ replace_fterms t2) |
55 | NONE => replace_fterms t1 $ replace_fterms t2) |
56 | replace_fterms t = (case AList.lookup (op aconv) env t of |
56 | replace_fterms t = (case AList.lookup (op aconv) env t of |
57 SOME v => v |
57 SOME v => v |
58 | NONE => t) |
58 | NONE => t) |
59 |
59 |
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))) |
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)) |
61 | mk_def (t, v) = HOLogic.mk_Trueprop (HOLogic.mk_eq (v, t)) |
62 fun tryext x = (x RS ext2 handle THM _ => x) |
62 fun tryext x = (x RS ext2 handle THM _ => x) |
63 val cong = (Goal.prove ctxt'' [] (map mk_def env) |
63 val cong = (Goal.prove ctxt'' [] (map mk_def env) |
64 (HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, replace_fterms rhs))) |
64 (HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, replace_fterms rhs))) |
65 (fn x => LocalDefs.unfold_tac (#context x) (map tryext (#prems x)) |
65 (fn x => LocalDefs.unfold_tac (#context x) (map tryext (#prems x)) |
66 THEN rtac th' 1)) RS sym |
66 THEN rtac th' 1)) RS sym |
67 |
67 |
68 val (cong' :: vars') = |
68 val (cong' :: vars') = |
69 Variable.export ctxt'' ctxt (cong :: map (Drule.mk_term o cert) vs) |
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' |
70 val vs' = map (fst o fst o Term.dest_Var o Thm.term_of o Drule.dest_term) vars' |
71 |
71 |
72 in (vs', cong') end; |
72 in (vs', cong') end; |
73 (* congs is a list of pairs (P,th) where th is a theorem for *) |
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 *) |
74 (* [| f p1 = A1; ...; f pn = An|] ==> f (C p1 .. pn) = P *) |
75 val FWD = curry (op OF); |
75 val FWD = curry (op OF); |
76 |
76 |
77 (* da is the decomposition for atoms, ie. it returns ([],g) where g |
|
78 returns the right instance f (AtC n) = t , where AtC is the Atoms |
|
79 constructor and n is the number of the atom corresponding to t *) |
|
80 |
|
81 (* Generic decomp for reification : matches the actual term with the |
|
82 rhs of one cong rule. The result of the matching guides the |
|
83 proof synthesis: The matches of the introduced Variables A1 .. An are |
|
84 processed recursively |
|
85 The rest is instantiated in the cong rule,i.e. no reification is needed *) |
|
86 |
77 |
87 exception REIF of string; |
78 exception REIF of string; |
88 |
79 |
89 fun dest_listT (Type ("List.list", [T])) = T; |
80 fun dest_listT (Type ("List.list", [T])) = T; |
90 |
81 |
91 fun rearrange congs = |
82 fun rearrange congs = |
92 let |
83 let |
93 fun P (_, th) = |
84 fun P (_, th) = |
94 let val @{term "Trueprop"}$(Const ("op =",_) $l$_) = concl_of th |
85 let val @{term "Trueprop"}$(Const ("op =",_) $l$_) = concl_of th |
95 in can dest_Var l end |
86 in can dest_Var l end |
96 val (yes,no) = List.partition P congs |
87 val (yes,no) = List.partition P congs |
97 in no @ yes end |
88 in no @ yes end |
98 |
89 |
99 fun genreif ctxt raw_eqs t = |
90 fun genreif ctxt raw_eqs t = |
100 let |
91 let |
101 val bds = ref ([]: (typ * ((term list) * (term list))) list); |
92 val bds = ref ([]: (typ * ((term list) * (term list))) list); |
102 |
93 |
103 fun index_of t = |
94 fun index_of t = |
104 let |
95 let |
105 val tt = HOLogic.listT (fastype_of t) |
96 val tt = HOLogic.listT (fastype_of t) |
106 in |
97 in |
107 (case AList.lookup Type.could_unify (!bds) tt of |
98 (case AList.lookup Type.could_unify (!bds) tt of |
108 NONE => error "index_of : type not found in environements!" |
99 NONE => error "index_of : type not found in environements!" |
109 | SOME (tbs,tats) => |
100 | SOME (tbs,tats) => |
110 let |
101 let |
111 val i = find_index_eq t tats |
102 val i = find_index_eq t tats |
112 val j = find_index_eq t tbs |
103 val j = find_index_eq t tbs |
113 in (if j= ~1 then |
104 in (if j= ~1 then |
114 if i= ~1 |
105 if i= ~1 |
115 then (bds := AList.update Type.could_unify (tt,(tbs,tats@[t])) (!bds) ; |
106 then (bds := AList.update Type.could_unify (tt,(tbs,tats@[t])) (!bds) ; |
116 length tbs + length tats) |
107 length tbs + length tats) |
117 else i else j) |
108 else i else j) |
118 end) |
109 end) |
119 end; |
110 end; |
120 |
111 |
121 fun decomp_genreif da cgns (t,ctxt) = |
112 (* Generic decomp for reification : matches the actual term with the |
122 let |
113 rhs of one cong rule. The result of the matching guides the |
123 val thy = ProofContext.theory_of ctxt |
114 proof synthesis: The matches of the introduced Variables A1 .. An are |
124 val cert = cterm_of thy |
115 processed recursively |
125 fun tryabsdecomp (s,ctxt) = |
116 The rest is instantiated in the cong rule,i.e. no reification is needed *) |
126 (case s of |
117 |
127 Abs(xn,xT,ta) => |
118 (* da is the decomposition for atoms, ie. it returns ([],g) where g |
128 (let |
119 returns the right instance f (AtC n) = t , where AtC is the Atoms |
129 val ([xn],ctxt') = Variable.variant_fixes ["x"] ctxt |
120 constructor and n is the number of the atom corresponding to t *) |
130 val (xn,ta) = variant_abs (xn,xT,ta) |
121 fun decomp_genreif da cgns (t,ctxt) = |
131 val x = Free(xn,xT) |
122 let |
132 val _ = (case AList.lookup Type.could_unify (!bds) (HOLogic.listT xT) |
123 val thy = ProofContext.theory_of ctxt |
133 of NONE => error "tryabsdecomp: Type not found in the Environement" |
|
134 | SOME (bsT,atsT) => |
|
135 (bds := AList.update Type.could_unify (HOLogic.listT xT, ((x::bsT), atsT)) (!bds))) |
|
136 in ([(ta, ctxt')] , |
|
137 fn [th] => ((let val (bsT,asT) = the(AList.lookup Type.could_unify (!bds) (HOLogic.listT xT)) |
|
138 in (bds := AList.update Type.could_unify (HOLogic.listT xT,(tl bsT,asT)) (!bds)) |
|
139 end) ; |
|
140 hd (Variable.export ctxt' ctxt [(forall_intr (cert x) th) COMP allI]))) |
|
141 end) |
|
142 | _ => da (s,ctxt)) |
|
143 in |
|
144 (case cgns of |
|
145 [] => tryabsdecomp (t,ctxt) |
|
146 | ((vns,cong)::congs) => ((let |
|
147 val cert = cterm_of thy |
124 val cert = cterm_of thy |
148 val certy = ctyp_of thy |
125 fun tryabsdecomp (s,ctxt) = |
149 val (tyenv, tmenv) = |
126 (case s of |
150 Pattern.match thy |
127 Abs(xn,xT,ta) => ( |
151 ((fst o HOLogic.dest_eq o HOLogic.dest_Trueprop) (concl_of cong), t) |
128 let |
152 (Envir.type_env (Envir.empty 0), Vartab.empty) |
129 val ([xn],ctxt') = Variable.variant_fixes ["x"] ctxt |
153 val (fnvs,invs) = List.partition (fn ((vn,_),_) => vn mem vns) (Vartab.dest tmenv) |
130 val (xn,ta) = variant_abs (xn,xT,ta) |
154 val (fts,its) = |
131 val x = Free(xn,xT) |
155 (map (snd o snd) fnvs, |
132 val _ = (case AList.lookup Type.could_unify (!bds) (HOLogic.listT xT) |
156 map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) invs) |
133 of NONE => error "tryabsdecomp: Type not found in the Environement" |
157 val ctyenv = map (fn ((vn,vi),(s,ty)) => (certy (TVar((vn,vi),s)), certy ty)) (Vartab.dest tyenv) |
134 | SOME (bsT,atsT) => |
158 in (fts ~~ (replicate (length fts) ctxt), FWD (instantiate (ctyenv, its) cong)) |
135 (bds := AList.update Type.could_unify (HOLogic.listT xT, ((x::bsT), atsT)) (!bds))) |
159 end) |
136 in ([(ta, ctxt')] , |
160 handle MATCH => decomp_genreif da congs (t,ctxt))) |
137 fn [th] => ((let val (bsT,asT) = the(AList.lookup Type.could_unify (!bds) (HOLogic.listT xT)) |
161 end; |
138 in (bds := AList.update Type.could_unify (HOLogic.listT xT,(tl bsT,asT)) (!bds)) |
|
139 end) ; |
|
140 hd (Variable.export ctxt' ctxt [(forall_intr (cert x) th) COMP allI]))) |
|
141 end) |
|
142 | _ => da (s,ctxt)) |
|
143 in (case cgns of |
|
144 [] => tryabsdecomp (t,ctxt) |
|
145 | ((vns,cong)::congs) => ((let |
|
146 val cert = cterm_of thy |
|
147 val certy = ctyp_of thy |
|
148 val (tyenv, tmenv) = |
|
149 Pattern.match thy |
|
150 ((fst o HOLogic.dest_eq o HOLogic.dest_Trueprop) (concl_of cong), t) |
|
151 (Envir.type_env (Envir.empty 0), Vartab.empty) |
|
152 val (fnvs,invs) = List.partition (fn ((vn,_),_) => vn mem vns) (Vartab.dest tmenv) |
|
153 val (fts,its) = |
|
154 (map (snd o snd) fnvs, |
|
155 map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) invs) |
|
156 val ctyenv = map (fn ((vn,vi),(s,ty)) => (certy (TVar((vn,vi),s)), certy ty)) (Vartab.dest tyenv) |
|
157 in (fts ~~ (replicate (length fts) ctxt), FWD (instantiate (ctyenv, its) cong)) |
|
158 end) |
|
159 handle MATCH => decomp_genreif da congs (t,ctxt))) |
|
160 end; |
162 |
161 |
163 (* looks for the atoms equation and instantiates it with the right number *) |
162 (* looks for the atoms equation and instantiates it with the right number *) |
164 fun mk_decompatom eqs (t,ctxt) = |
163 fun mk_decompatom eqs (t,ctxt) = |
165 let |
164 let |
166 val tT = fastype_of t |
165 val tT = fastype_of t |
167 fun isat eq = |
166 fun isat eq = |
168 let |
167 let |
169 val rhs = eq |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd |
168 val rhs = eq |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd |
170 in exists_Const |
169 in exists_Const |
171 (fn (n,ty) => n="List.nth" |
170 (fn (n,ty) => n="List.nth" |
172 andalso |
171 andalso |
173 AList.defined Type.could_unify (!bds) (domain_type ty)) rhs |
172 AList.defined Type.could_unify (!bds) (domain_type ty)) rhs |
174 andalso Type.could_unify (fastype_of rhs, tT) |
173 andalso Type.could_unify (fastype_of rhs, tT) |
175 end |
174 end |
176 fun get_nths t acc = |
175 |
177 case t of |
176 fun get_nths t acc = |
178 Const("List.nth",_)$vs$n => insert (fn ((a,_),(b,_)) => a aconv b) (t,(vs,n)) acc |
177 case t of |
179 | t1$t2 => get_nths t1 (get_nths t2 acc) |
178 Const("List.nth",_)$vs$n => insert (fn ((a,_),(b,_)) => a aconv b) (t,(vs,n)) acc |
180 | Abs(_,_,t') => get_nths t' acc |
179 | t1$t2 => get_nths t1 (get_nths t2 acc) |
181 | _ => acc |
180 | Abs(_,_,t') => get_nths t' acc |
182 |
181 | _ => acc |
183 fun |
182 |
184 tryeqs [] = error "Can not find the atoms equation" |
183 fun |
185 | tryeqs (eq::eqs) = (( |
184 tryeqs [] = error "Can not find the atoms equation" |
186 let |
185 | tryeqs (eq::eqs) = (( |
187 val rhs = eq |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd |
186 let |
188 val nths = get_nths rhs [] |
187 val rhs = eq |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd |
189 val (vss,ns) = fold_rev (fn (_,(vs,n)) => fn (vss,ns) => |
188 val nths = get_nths rhs [] |
190 (insert (op aconv) vs vss, insert (op aconv) n ns)) nths ([],[]) |
189 val (vss,ns) = fold_rev (fn (_,(vs,n)) => fn (vss,ns) => |
191 val (vsns, ctxt') = Variable.variant_fixes (replicate (length vss) "vs") ctxt |
190 (insert (op aconv) vs vss, insert (op aconv) n ns)) nths ([],[]) |
192 val (xns, ctxt'') = Variable.variant_fixes (replicate (length nths) "x") ctxt' |
191 val (vsns, ctxt') = Variable.variant_fixes (replicate (length vss) "vs") ctxt |
193 val thy = ProofContext.theory_of ctxt'' |
192 val (xns, ctxt'') = Variable.variant_fixes (replicate (length nths) "x") ctxt' |
194 val cert = cterm_of thy |
193 val thy = ProofContext.theory_of ctxt'' |
195 val certT = ctyp_of thy |
194 val cert = cterm_of thy |
196 val vsns_map = vss ~~ vsns |
195 val certT = ctyp_of thy |
197 val xns_map = (fst (split_list nths)) ~~ xns |
196 val vsns_map = vss ~~ vsns |
198 val subst = map (fn (nt, xn) => (nt, Var ((xn,0), fastype_of nt))) xns_map |
197 val xns_map = (fst (split_list nths)) ~~ xns |
199 val rhs_P = subst_free subst rhs |
198 val subst = map (fn (nt, xn) => (nt, Var ((xn,0), fastype_of nt))) xns_map |
200 val (tyenv, tmenv) = Pattern.match |
199 val rhs_P = subst_free subst rhs |
201 thy (rhs_P, t) |
200 val (tyenv, tmenv) = Pattern.match |
202 (Envir.type_env (Envir.empty 0), Vartab.empty) |
201 thy (rhs_P, t) |
203 val sbst = Envir.subst_vars (tyenv, tmenv) |
202 (Envir.type_env (Envir.empty 0), Vartab.empty) |
204 val sbsT = Envir.typ_subst_TVars tyenv |
203 val sbst = Envir.subst_vars (tyenv, tmenv) |
205 val subst_ty = map (fn (n,(s,t)) => (certT (TVar (n, s)), certT t)) |
204 val sbsT = Envir.typ_subst_TVars tyenv |
206 (Vartab.dest tyenv) |
205 val subst_ty = map (fn (n,(s,t)) => (certT (TVar (n, s)), certT t)) |
207 val tml = Vartab.dest tmenv |
206 (Vartab.dest tyenv) |
208 val t's = map (fn xn => snd (valOf (AList.lookup (op =) tml (xn,0)))) xns (* FIXME : Express with sbst*) |
207 val tml = Vartab.dest tmenv |
209 val subst_ns = map (fn (Const _ $ vs $ n, Var (xn0,T)) => |
208 val t's = map (fn xn => snd (valOf (AList.lookup (op =) tml (xn,0)))) xns (* FIXME : Express with sbst*) |
210 (cert n, snd (valOf (AList.lookup (op =) tml xn0)) |
209 val subst_ns = map (fn (Const _ $ vs $ n, Var (xn0,T)) => |
211 |> (index_of #> HOLogic.mk_nat #> cert))) |
210 (cert n, snd (valOf (AList.lookup (op =) tml xn0)) |
212 subst |
211 |> (index_of #> HOLogic.mk_nat #> cert))) |
213 val subst_vs = |
212 subst |
214 let |
213 val subst_vs = |
215 fun ty (Const _ $ (vs as Var (vsn,lT)) $ n, Var (xn0,T)) = (certT T, certT (sbsT T)) |
214 let |
216 fun h (Const _ $ (vs as Var (vsn,lT)) $ n, Var (xn0,T)) = |
215 fun ty (Const _ $ (vs as Var (vsn,lT)) $ n, Var (xn0,T)) = (certT T, certT (sbsT T)) |
217 let |
216 fun h (Const _ $ (vs as Var (vsn,lT)) $ n, Var (xn0,T)) = |
218 val cns = sbst (Const("List.list.Cons", T --> lT --> lT)) |
217 let |
219 val lT' = sbsT lT |
218 val cns = sbst (Const("List.list.Cons", T --> lT --> lT)) |
220 val (bsT,asT) = the (AList.lookup Type.could_unify (!bds) lT) |
219 val lT' = sbsT lT |
221 val vsn = valOf (AList.lookup (op =) vsns_map vs) |
220 val (bsT,asT) = the (AList.lookup Type.could_unify (!bds) lT) |
222 val cvs = cert (fold_rev (fn x => fn xs => cns$x$xs) bsT (Free (vsn, lT'))) |
221 val vsn = valOf (AList.lookup (op =) vsns_map vs) |
223 in (cert vs, cvs) end |
222 val cvs = cert (fold_rev (fn x => fn xs => cns$x$xs) bsT (Free (vsn, lT'))) |
224 in map h subst end |
223 in (cert vs, cvs) end |
225 val cts = map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) |
224 in map h subst end |
226 (fold (AList.delete (fn (((a: string),_),(b,_)) => a = b)) |
225 val cts = map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) |
227 (map (fn n => (n,0)) xns) tml) |
226 (fold (AList.delete (fn (((a: string),_),(b,_)) => a = b)) |
228 val substt = |
227 (map (fn n => (n,0)) xns) tml) |
229 let val ih = Drule.cterm_rule (Thm.instantiate (subst_ty,[])) |
228 val substt = |
230 in map (fn (v,t) => (ih v, ih t)) (subst_ns@subst_vs@cts) end |
229 let val ih = Drule.cterm_rule (Thm.instantiate (subst_ty,[])) |
231 val th = (instantiate (subst_ty, substt) eq) RS sym |
230 in map (fn (v,t) => (ih v, ih t)) (subst_ns@subst_vs@cts) end |
232 in hd (Variable.export ctxt'' ctxt [th]) end) |
231 val th = (instantiate (subst_ty, substt) eq) RS sym |
233 handle MATCH => tryeqs eqs) |
232 in hd (Variable.export ctxt'' ctxt [th]) end) |
234 in ([], fn _ => tryeqs (filter isat eqs)) |
233 handle MATCH => tryeqs eqs) |
235 end; |
234 in ([], fn _ => tryeqs (filter isat eqs)) |
|
235 end; |
236 |
236 |
237 (* Generic reification procedure: *) |
237 (* Generic reification procedure: *) |
238 (* creates all needed cong rules and then just uses the theorem synthesis *) |
238 (* creates all needed cong rules and then just uses the theorem synthesis *) |
239 |
239 |
240 fun mk_congs ctxt raw_eqs = |
240 fun mk_congs ctxt raw_eqs = |
241 let |
241 let |
242 val fs = fold_rev (fn eq => |
242 val fs = fold_rev (fn eq => |
243 insert (op =) (eq |> prop_of |> HOLogic.dest_Trueprop |
243 insert (op =) (eq |> prop_of |> HOLogic.dest_Trueprop |
244 |> HOLogic.dest_eq |> fst |> strip_comb |
244 |> HOLogic.dest_eq |> fst |> strip_comb |
245 |> fst)) raw_eqs [] |
245 |> fst)) raw_eqs [] |
246 val tys = fold_rev (fn f => fold (insert (op =)) (f |> fastype_of |> binder_types |> tl) |
246 val tys = fold_rev (fn f => fold (insert (op =)) (f |> fastype_of |> binder_types |> tl) |
247 ) fs [] |
247 ) fs [] |
248 val _ = bds := AList.make (fn _ => ([],[])) tys |
248 val _ = bds := AList.make (fn _ => ([],[])) tys |
249 val (vs, ctxt') = Variable.variant_fixes (replicate (length tys) "vs") ctxt |
249 val (vs, ctxt') = Variable.variant_fixes (replicate (length tys) "vs") ctxt |
250 val thy = ProofContext.theory_of ctxt' |
250 val thy = ProofContext.theory_of ctxt' |
251 val cert = cterm_of thy |
251 val cert = cterm_of thy |
252 val vstys = map (fn (t,v) => (t,SOME (cert (Free(v,t))))) |
252 val vstys = map (fn (t,v) => (t,SOME (cert (Free(v,t))))) |
253 (tys ~~ vs) |
253 (tys ~~ vs) |
254 val is_Var = can dest_Var |
254 val is_Var = can dest_Var |
255 fun insteq eq vs = |
255 fun insteq eq vs = |
256 let |
256 let |
257 val subst = map (fn (v as Var(n,t)) => (cert v, (valOf o valOf) (AList.lookup (op =) vstys t))) |
257 val subst = map (fn (v as Var(n,t)) => (cert v, (valOf o valOf) (AList.lookup (op =) vstys t))) |
258 (filter is_Var vs) |
258 (filter is_Var vs) |
259 in Thm.instantiate ([],subst) eq |
259 in Thm.instantiate ([],subst) eq |
260 end |
260 end |
261 val eqs = map (fn eq => eq |> prop_of |> HOLogic.dest_Trueprop |
261 |
262 |> HOLogic.dest_eq |> fst |> strip_comb |> snd |> tl |
262 val eqs = map (fn eq => eq |> prop_of |> HOLogic.dest_Trueprop |
263 |> (insteq eq)) raw_eqs |
263 |> HOLogic.dest_eq |> fst |> strip_comb |> snd |> tl |
264 val (ps,congs) = split_list (map (mk_congeq ctxt' fs) eqs) |
264 |> (insteq eq)) raw_eqs |
265 in ps ~~ (Variable.export ctxt' ctxt congs) |
265 val (ps,congs) = split_list (map (mk_congeq ctxt' fs) eqs) |
266 end |
266 in ps ~~ (Variable.export ctxt' ctxt congs) |
267 |
267 end |
268 val congs = rearrange (mk_congs ctxt raw_eqs) |
268 |
269 val th = divide_and_conquer (decomp_genreif (mk_decompatom raw_eqs) congs) (t,ctxt) |
269 val congs = rearrange (mk_congs ctxt raw_eqs) |
270 fun is_listVar (Var (_,t)) = can dest_listT t |
270 val th = divide_and_conquer (decomp_genreif (mk_decompatom raw_eqs) congs) (t,ctxt) |
271 | is_listVar _ = false |
271 fun is_listVar (Var (_,t)) = can dest_listT t |
272 val vars = th |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd |
272 | is_listVar _ = false |
273 |> strip_comb |> snd |> filter is_listVar |
273 val vars = th |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd |
274 val cert = cterm_of (ProofContext.theory_of ctxt) |
274 |> strip_comb |> snd |> filter is_listVar |
275 val cvs = map (fn (v as Var(n,t)) => (cert v, the (AList.lookup Type.could_unify (!bds) t) |> snd |> HOLogic.mk_list (dest_listT t) |> cert)) vars |
275 val cert = cterm_of (ProofContext.theory_of ctxt) |
276 val th' = instantiate ([], cvs) th |
276 val cvs = map (fn (v as Var(n,t)) => (cert v, |
277 val t' = (fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of) th' |
277 the (AList.lookup Type.could_unify (!bds) t) |> snd |> HOLogic.mk_list (dest_listT t) |> cert)) vars |
278 val th'' = Goal.prove ctxt [] [] (HOLogic.mk_Trueprop (HOLogic.mk_eq (t, t'))) |
278 val th' = instantiate ([], cvs) th |
279 (fn _ => simp_tac (local_simpset_of ctxt) 1) |
279 val t' = (fst o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of) th' |
280 val _ = bds := [] |
280 val th'' = Goal.prove ctxt [] [] (HOLogic.mk_Trueprop (HOLogic.mk_eq (t, t'))) |
281 in FWD trans [th'',th'] |
281 (fn _ => simp_tac (local_simpset_of ctxt) 1) |
282 end |
282 val _ = bds := [] |
|
283 in FWD trans [th'',th'] |
|
284 end |
283 |
285 |
284 |
286 |
285 fun genreflect ctxt conv corr_thms raw_eqs t = |
287 fun genreflect ctxt conv corr_thms raw_eqs t = |
286 let |
288 let |
287 val reifth = genreif ctxt raw_eqs t |
289 val reifth = genreif ctxt raw_eqs t |
288 fun trytrans [] = error "No suitable correctness theorem found" |
290 fun trytrans [] = error "No suitable correctness theorem found" |
289 | trytrans (th::ths) = |
291 | trytrans (th::ths) = |
290 (FWD trans [reifth, th RS sym] handle THM _ => trytrans ths) |
292 (FWD trans [reifth, th RS sym] handle THM _ => trytrans ths) |
291 val th = trytrans corr_thms |
293 val th = trytrans corr_thms |
292 val ft = (Thm.dest_arg1 o Thm.dest_arg o Thm.dest_arg o cprop_of) th |
294 val ft = (Thm.dest_arg1 o Thm.dest_arg o Thm.dest_arg o cprop_of) th |
293 val rth = conv ft |
295 val rth = conv ft |
294 in simplify (HOL_basic_ss addsimps raw_eqs addsimps [nth_Cons_0, nth_Cons_Suc]) |
296 in simplify (HOL_basic_ss addsimps raw_eqs addsimps [nth_Cons_0, nth_Cons_Suc]) |
295 (simplify (HOL_basic_ss addsimps [rth]) th) |
297 (simplify (HOL_basic_ss addsimps [rth]) th) |
296 end |
298 end |
297 |
299 |
298 fun genreify_tac ctxt eqs to i = (fn st => |
300 fun genreify_tac ctxt eqs to i = (fn st => |
299 let |
301 let |
300 fun P () = HOLogic.dest_Trueprop (List.nth (prems_of st, i - 1)) |
302 fun P () = HOLogic.dest_Trueprop (List.nth (prems_of st, i - 1)) |
301 val t = (case to of NONE => P () | SOME x => x) |
303 val t = (case to of NONE => P () | SOME x => x) |