]> matita.cs.unibo.it Git - helm.git/blob - helm/software/components/ng_paramodulation/nCicBlob.ml
proof reconstruction almost OK
[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 p 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 p));
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 p))
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 rec aux ongoal seen = function
186       | [] -> NCic.Rel 1
187       | id :: tl ->
188           let amount = List.length seen in
189           let _, lit, vl, proof = Terms.M.find id bag in
190           let lit = 
191             match lit with 
192             | Terms.Predicate t -> assert false 
193             | Terms.Equation (l,r,ty,_) -> 
194                  Terms.Node [ Terms.Leaf eqP; ty; l; r]
195           in
196           if not ongoal && id = mp then
197             (assert (vl = []);  
198              NCic.LetIn ("clause_" ^ string_of_int id, 
199                 extract amount vl lit, 
200                 (NCic.Appl [eq_refl;NCic.Implicit `Type;NCic.Implicit `Term]),
201                 aux true ((id,([],lit))::seen) (id::tl)))
202           else
203           match proof with
204           | Terms.Exact _ when tl=[] -> aux ongoal seen tl
205           | Terms.Step _ when tl=[] -> assert false
206           | Terms.Exact ft -> 
207                NCic.LetIn ("clause_" ^ string_of_int id, 
208                  close_with_forall vl (extract amount vl lit),
209                  close_with_lambdas vl (extract amount vl ft),
210                  aux ongoal 
211                    ((id,(List.map (fun x -> Terms.Var x) vl,lit))::seen) tl)
212           | Terms.Step (_, id1, id2, dir, pos, subst) ->
213               let id, id1 = if ongoal then id1,id else id,id1 in
214               let proof_of_id id = 
215                 let vars = List.rev (vars_of id seen) in
216                 let args = List.map (Subst.apply_subst subst) vars in
217                 let args = List.map (extract amount vl) args in
218                 NCic.Appl (NCic.Rel (List.length vl + position id seen) :: args)
219               in
220               let p_id1 = proof_of_id id1 in
221               let p_id2 = proof_of_id id2 in
222               let pred, hole_type, l, r = 
223                 let id1_ty = ty_of id1 seen in
224                 let id2_ty,l,r = 
225                   match ty_of id2 seen with
226                   | Terms.Node [ _; t; l; r ] -> 
227                       extract amount vl (Subst.apply_subst subst t),
228                       extract amount vl (Subst.apply_subst subst l),
229                       extract amount vl (Subst.apply_subst subst r)
230                   | _ -> assert false
231                 in
232                 mk_predicate 
233                   id2_ty amount (Subst.apply_subst subst id1_ty) pos vl,
234                 id2_ty,
235                 l,r
236               in
237               let l, r, eq_ind = 
238                 if (ongoal=true) = (dir=Terms.Left2Right) then
239                   r,l,eq_ind_r
240                 else
241                   l,r,eq_ind
242               in
243                NCic.LetIn ("clause_" ^ string_of_int id, 
244                  close_with_forall vl (extract amount vl lit),
245                  close_with_lambdas vl
246                    (NCic.Appl [ eq_ind ; hole_type; l; pred; p_id1; r; p_id2 ]),
247                  aux ongoal 
248                    ((id,(List.map (fun x -> Terms.Var x) vl,lit))::seen) tl)
249     in 
250       aux false [] steps
251   ;;
252
253  end