]> matita.cs.unibo.it Git - helm.git/blob - helm/software/components/ng_paramodulation/nCicBlob.ml
Fixed nasty bug in maxvar updating
[helm.git] / helm / software / components / ng_paramodulation / nCicBlob.ml
1 (*
2     ||M||  This file is part of HELM, an Hypertextual, Electronic        
3     ||A||  Library of Mathematics, developed at the Computer Science     
4     ||T||  Department, University of Bologna, Italy.                     
5     ||I||                                                                
6     ||T||  HELM is free software; you can redistribute it and/or         
7     ||A||  modify it under the terms of the GNU General Public License   
8     \   /  version 2 or (at your option) any later version.      
9      \ /   This software is distributed as is, NO WARRANTY.     
10       V_______________________________________________________________ *)
11
12 (* $Id: terms.mli 9822 2009-06-03 15:37:06Z tassi $ *)
13
14 module type NCicContext =
15   sig
16     val metasenv : NCic.metasenv
17     val subst : NCic.substitution
18     val context : NCic.context
19   end
20
21 module NCicBlob(C : NCicContext) : Terms.Blob with type t = NCic.term = struct
22
23   type t = NCic.term
24
25   let eq x y = NCicReduction.alpha_eq C.metasenv C.subst C.context x y;;
26
27   let rec compare x y = 
28     match x,y with
29     | NCic.Rel i, NCic.Rel j -> i-j
30     | NCic.Meta (i,_), NCic.Meta (j,_) -> i-j
31     | NCic.Const r1, NCic.Const r2 -> NReference.compare r1 r2
32     | NCic.Appl l1, NCic.Appl l2 -> FoUtils.lexicograph compare l1 l2
33     | NCic.Rel _, ( NCic.Meta _ | NCic.Const _ | NCic.Appl _ ) -> ~-1
34     | ( NCic.Meta _ | NCic.Const _ | NCic.Appl _ ), NCic.Rel _ -> 1
35     | NCic.Const _, ( NCic.Meta _ | NCic.Appl _ ) -> ~-1
36     | ( NCic.Meta _ | NCic.Appl _ ), NCic.Const _ -> 1
37     | NCic.Appl _, NCic.Meta _ -> ~-1
38     | NCic.Meta _, NCic.Appl _ -> 1
39     | _ -> assert false
40   ;;
41   
42   let compare x y = 
43     if NCicReduction.alpha_eq C.metasenv C.subst C.context x y then 0 
44     else compare x y
45   ;;
46
47   let pp t = 
48     NCicPp.ppterm ~context:C.context ~metasenv:C.metasenv ~subst:C.subst t;;
49
50   let rec embed = function
51     | NCic.Meta (i,_) -> Terms.Var i, [i]
52     | NCic.Appl l ->
53         let rec aux acc l = function
54           |[] -> acc@l
55           |hd::tl -> if List.mem hd l then aux acc l tl else aux (hd::acc) l tl
56         in
57         let res,vars = List.fold_left
58           (fun (r,v) t -> let r1,v1 = embed t in (r1::r),aux [] v v1) ([],[]) l
59         in (Terms.Node (List.rev res)), vars
60     | t -> Terms.Leaf t, []
61   ;;
62
63   let embed t = fst (embed t) ;;
64
65   let saturate t ty = 
66     let sty, _, args = 
67       NCicMetaSubst.saturate ~delta:max_int C.metasenv C.subst C.context
68         ty 0
69     in
70     let proof = 
71       if args = [] then Terms.Leaf t 
72       else Terms.Node (Terms.Leaf t :: List.map embed args)
73     in
74     let sty = embed sty in
75     proof, sty
76   ;;
77
78   let eqP = 
79     let r = 
80       OCic2NCic.reference_of_oxuri 
81        (UriManager.uri_of_string 
82          "cic:/matita/logic/equality/eq.ind#xpointer(1/1)")
83     in
84     NCic.Const r
85   ;;
86
87   let eq_ind = 
88     let r = 
89       OCic2NCic.reference_of_oxuri 
90        (UriManager.uri_of_string 
91          "cic:/matita/logic/equality/eq_ind.con")
92     in
93     NCic.Const r
94   ;;
95
96   let eq_ind_r = 
97     let r = 
98       OCic2NCic.reference_of_oxuri 
99        (UriManager.uri_of_string 
100          "cic:/matita/logic/equality/eq_elim_r.con")
101     in
102     NCic.Const r
103   ;;
104
105   let eq_refl = 
106     let r = 
107       OCic2NCic.reference_of_oxuri 
108        (UriManager.uri_of_string 
109          "cic:/matita/logic/equality/eq.ind#xpointer(1/1/1)")
110     in
111     NCic.Const r
112   ;;
113
114   let extract lift vl t =
115     let rec pos i = function 
116       | [] -> raise Not_found 
117       | j :: tl when j <> i -> 1+ pos i tl
118       | _ -> 1
119     in
120     let vl_len = List.length vl in
121     let rec extract = function
122       | Terms.Leaf x -> NCicSubstitution.lift (vl_len+lift) x
123       | Terms.Var j -> 
124            (try NCic.Rel (pos j vl) with Not_found -> NCic.Implicit `Term) 
125       | Terms.Node l -> NCic.Appl (List.map extract l)
126     in
127       extract t
128   ;;
129
130    let rec ppfot = function 
131      | Terms.Leaf _ -> "."
132      | Terms.Var i -> "?" ^ string_of_int i
133      | Terms.Node l -> "(" ^ String.concat " " (List.map ppfot l) ^ ")"
134    ;;
135
136    let mk_predicate hole_type amount ft p1 vl =
137     let rec aux t p = 
138       match p with
139       | [] -> NCic.Rel 1
140       | n::tl ->
141           match t with
142           | Terms.Leaf _ 
143           | Terms.Var _ -> 
144                prerr_endline ("term: " ^ ppfot ft);            
145                prerr_endline ("path: " ^ String.concat "," 
146                  (List.map string_of_int p1));
147                assert false
148           | Terms.Node l -> 
149               let l = 
150                 HExtlib.list_mapi
151                   (fun t i -> 
152                     if i = n then aux t tl 
153                     else extract amount (0::vl) t)
154                   l
155               in            
156               NCic.Appl l
157     in
158       NCic.Lambda("x", hole_type, aux ft (List.rev p1))
159     ;;
160
161   let mk_proof (bag : NCic.term Terms.bag) mp steps =
162     let module Subst = FoSubst in
163     let position i l = 
164       let rec aux = function
165        | [] -> assert false
166        | (j,_) :: tl when i = j -> 1
167        | _ :: tl -> 1 + aux tl
168       in
169         aux l
170     in
171     let vars_of i l = fst (List.assoc i l) in
172     let ty_of i l = snd (List.assoc i l) in
173     let close_with_lambdas vl t = 
174       List.fold_left 
175        (fun t i -> 
176           NCic.Lambda ("x"^string_of_int i, NCic.Implicit `Type, t))
177        t vl  
178     in
179     let close_with_forall vl t = 
180       List.fold_left 
181        (fun t i -> 
182           NCic.Prod ("x"^string_of_int i, NCic.Implicit `Type, t))
183        t vl  
184     in
185     let get_literal id =
186       let _, lit, vl, proof = Terms.M.find id bag in
187       let lit =match lit with 
188           | Terms.Predicate t -> assert false 
189           | Terms.Equation (l,r,ty,_) -> 
190               Terms.Node [ Terms.Leaf eqP; ty; l; r]
191       in
192         lit, vl, proof
193     in
194     let rec aux ongoal seen = function
195       | [] -> NCic.Rel 1
196       | id :: tl ->
197           let amount = List.length seen in
198           let lit,vl,proof = get_literal id in
199           if not ongoal && id = mp then
200             ((*prerr_endline ("Reached m point, id=" ^ (string_of_int id));*)
201              assert (vl = []);  
202              NCic.LetIn ("clause_" ^ string_of_int id, 
203                 extract amount vl lit, 
204                 (NCic.Appl [eq_refl;NCic.Implicit `Type;NCic.Implicit `Term]),
205                 aux true ((id,([],lit))::seen) (id::tl)))
206           else
207           match proof with
208           | Terms.Exact _ when tl=[] ->
209               (* prerr_endline ("Exact (tl=[]) for " ^ (string_of_int id));*)
210               aux ongoal seen tl
211           | Terms.Step _ when tl=[] -> assert false
212           | Terms.Exact ft ->
213               (* prerr_endline ("Exact for " ^ (string_of_int id));*)
214                NCic.LetIn ("clause_" ^ string_of_int id, 
215                  close_with_forall vl (extract amount vl lit),
216                  close_with_lambdas vl (extract amount vl ft),
217                  aux ongoal 
218                    ((id,(List.map (fun x -> Terms.Var x) vl,lit))::seen) tl)
219           | Terms.Step (_, id1, id2, dir, pos, subst) ->
220               let id, id1,(lit,vl,proof) =
221                 if ongoal then id1,id,get_literal id1
222                 else id,id1,(lit,vl,proof)
223               in
224               let vl = if ongoal then Subst.filter subst vl else vl in
225               let proof_of_id id = 
226                 let vars = List.rev (vars_of id seen) in
227                 let args = List.map (Subst.apply_subst subst) vars in
228                 let args = List.map (extract amount vl) args in
229                 let rel_for_id = NCic.Rel (List.length vl + position id seen) in
230                   if args = [] then rel_for_id              
231                   else NCic.Appl (rel_for_id::args)
232               in
233               let p_id1 = proof_of_id id1 in
234               let p_id2 = proof_of_id id2 in
235               let pred, hole_type, l, r = 
236                 let id1_ty = ty_of id1 seen in
237                 let id2_ty,l,r = 
238                   match ty_of id2 seen with
239                   | Terms.Node [ _; t; l; r ] -> 
240                       extract amount vl (Subst.apply_subst subst t),
241                       extract amount vl (Subst.apply_subst subst l),
242                       extract amount vl (Subst.apply_subst subst r)
243                   | _ -> assert false
244                 in
245                   (*prerr_endline "mk_predicate :";
246                   if ongoal then prerr_endline "ongoal=true"
247                   else prerr_endline "ongoal=false";
248                   prerr_endline ("id=" ^ string_of_int id);
249                   prerr_endline ("id1=" ^ string_of_int id1);
250                   prerr_endline ("id2=" ^ string_of_int id2);
251                   prerr_endline ("Positions :" ^
252                                    (String.concat ", "
253                                       (List.map string_of_int pos)));*)
254                 mk_predicate 
255                   id2_ty amount (Subst.apply_subst subst id1_ty) pos vl,
256                 id2_ty,
257                 l,r
258               in
259               let l, r, eq_ind = 
260                 if (ongoal=true) = (dir=Terms.Left2Right) then
261                   r,l,eq_ind_r
262                 else
263                   l,r,eq_ind
264               in
265                NCic.LetIn ("clause_" ^ string_of_int id, 
266                  close_with_forall vl (extract amount vl lit),
267                            (* NCic.Implicit `Type, *)
268                  close_with_lambdas vl 
269                    (NCic.Appl [ eq_ind ; hole_type; l; pred; p_id1; r; p_id2 ]),
270                  aux ongoal 
271                    ((id,(List.map (fun x -> Terms.Var x) vl,lit))::seen) tl)
272     in 
273       aux false [] steps
274   ;;
275
276  end