1
(************************************************************************)
2
(* v * The Coq Proof Assistant / The Coq Development Team *)
3
(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
4
(* \VV/ **************************************************************)
5
(* // * This file is distributed under the terms of the *)
6
(* * GNU Lesser General Public License Version 2.1 *)
7
(************************************************************************)
9
(*i $Id: instances.ml 10410 2007-12-31 13:11:55Z msozeau $ i*)
29
let compare_instance inst1 inst2=
30
match inst1,inst2 with
31
Phantom(d1),Phantom(d2)->
32
(OrderedConstr.compare d1 d2)
33
| Real((m1,c1),n1),Real((m2,c2),n2)->
34
((-) =? (-) ==? OrderedConstr.compare) m2 m1 n1 n2 c1 c2
35
| Phantom(_),Real((m,_),_)-> if m=0 then -1 else 1
36
| Real((m,_),_),Phantom(_)-> if m=0 then 1 else -1
38
let compare_gr id1 id2=
39
if id1==id2 then 0 else
40
if id1==dummy_id then 1
41
else if id2==dummy_id then -1
42
else Pervasives.compare id1 id2
44
module OrderedInstance=
46
type t=instance * Libnames.global_reference
47
let compare (inst1,id1) (inst2,id2)=
48
(compare_instance =? compare_gr) inst2 inst1 id2 id1
49
(* we want a __decreasing__ total order *)
52
module IS=Set.Make(OrderedInstance)
54
let make_simple_atoms seq=
59
in {negative=seq.latoms;positive=ratoms}
61
let do_sequent setref triv id seq i dom atoms=
66
match unif_atoms i dom t1 t2 with
68
| Some (Phantom _) ->phref:=true
69
| Some c ->flag:=false;setref:=IS.add (c,id) !setref in
70
List.iter (fun t->List.iter (do_pair t) a2.negative) a1.positive;
71
List.iter (fun t->List.iter (do_pair t) a2.positive) a1.negative in
72
HP.iter (fun lf->do_atoms atoms lf.atoms) seq.redexes;
73
do_atoms atoms (make_simple_atoms seq);
76
let match_one_quantified_hyp setref seq lf=
78
Left(Lforall(i,dom,triv))|Right(Rexists(i,dom,triv))->
79
if do_sequent setref triv lf.id seq i dom lf.atoms then
80
setref:=IS.add ((Phantom dom),lf.id) !setref
81
| _ ->anomaly "can't happen"
83
let give_instances lf seq=
84
let setref=ref IS.empty in
85
List.iter (match_one_quantified_hyp setref seq) lf;
88
(* collector for the engine *)
90
let rec collect_quantified seq=
92
let hd,seq1=take_formula seq in
94
Left(Lforall(_,_,_)) | Right(Rexists(_,_,_)) ->
95
let (q,seq2)=collect_quantified seq1 in
98
with Heap.EmptyHeap -> [],seq
100
(* open instances processor *)
102
let dummy_constr=mkMeta (-1)
104
let dummy_bvid=id_of_string "x"
106
let mk_open_instance id gl m t=
108
let evmap=Refiner.project gl in
110
if id==dummy_id then dummy_bvid else
111
let typ=pf_type_of gl (constr_of_global id) in
112
(* since we know we will get a product,
113
reduction is not too expensive *)
114
let (nam,_,_)=destProd (whd_betadeltaiota env evmap typ) in
117
| Anonymous -> dummy_bvid in
118
let revt=substl (list_tabulate (fun i->mkRel (m-i)) m) t in
121
let nid=(fresh_id avoid var_id gl) in
122
(Name nid,None,dummy_constr)::(aux (n-1) (nid::avoid)) in
123
let nt=it_mkLambda_or_LetIn revt (aux m []) in
124
let rawt=Detyping.detype false [] [] nt in
128
RLambda(loc,name,k,_,t0)->
129
let t1=raux (n-1) t0 in
130
RLambda(loc,name,k,RHole (dummy_loc,Evd.BinderType name),t1)
131
| _-> anomaly "can't happen" in
133
Pretyping.Default.understand evmap env (raux m rawt)
135
error "Untypable instance, maybe higher-order non-prenex quantification" in
136
Sign.decompose_lam_n_assum m ntt
140
let left_instance_tac (inst,id) continue seq=
143
if lookup (id,None) seq then
144
tclFAIL 0 (Pp.str "already done")
150
[mkApp(constr_of_global id,
151
[|mkVar (Tacmach.pf_nth_hyp_id gls 1)|])] gls);
153
tclSOLVE [wrap 1 false continue
154
(deepen (record (id,None) seq))]];
156
| Real((m,t) as c,_)->
157
if lookup (id,Some c) seq then
158
tclFAIL 0 (Pp.str "already done")
160
let special_generalize=
163
let (rc,ot)= mk_open_instance id gl m t in
166
(mkApp(constr_of_global id,[|ot|])) rc in
169
generalize [mkApp(constr_of_global id,[|t|])]
175
[wrap 1 false continue (deepen (record (id,Some c) seq))]]
177
let right_instance_tac inst continue seq=
184
split (Rawterm.ImplicitBindings
185
[mkVar (Tacmach.pf_nth_hyp_id gls 1)]) gls);
186
tclSOLVE [wrap 0 true continue (deepen seq)]];
189
(tclTHEN (split (Rawterm.ImplicitBindings [t]))
190
(tclSOLVE [wrap 0 true continue (deepen seq)]))
192
tclFAIL 0 (Pp.str "not implemented ... yet")
194
let instance_tac inst=
195
if (snd inst)==dummy_id then
196
right_instance_tac (fst inst)
198
left_instance_tac inst
200
let quantified_tac lf backtrack continue seq gl=
201
let insts=give_instances lf seq in
203
(tclFIRST (List.map (fun inst->instance_tac inst continue seq) insts))