]> matita.cs.unibo.it Git - helm.git/blob - helm/ocaml/tactics/fwdSimplTactic.ml
lapply improved
[helm.git] / helm / ocaml / tactics / fwdSimplTactic.ml
1 (* Copyright (C) 2002, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://cs.unibo.it/helm/.
24  *)
25
26 module MI = CicMkImplicit
27 module TC = CicTypeChecker 
28 module PET = ProofEngineTypes 
29 module PEH = ProofEngineHelpers 
30 module U  = CicUniv
31 module S = CicSubstitution
32 module PT = PrimitiveTactics
33 module T = Tacticals
34
35 let fail_msg1 = "no applicable simplification"
36
37 let error msg = raise (PET.Fail msg)
38
39 (* lapply *******************************************************************)
40
41 let strip_dependent_prods metasenv context t =
42    let irl = MI.identity_relocation_list_for_metavariable context in
43    let rec aux metasenv p xcontext = function
44       | Cic.Prod (name, t1, t2) when not (TC.does_not_occur xcontext 0 1 t2) ->  
45          let index = MI.new_meta metasenv [] in
46          let metasenv = [index, context, t1] @ metasenv in
47          let e, s = Some (name, Cic.Decl t1), Cic.Meta (index, irl) in    
48          aux metasenv (succ p) (e :: xcontext) (S.subst s t2)
49       | Cic.Prod (name, t1, t2) -> metasenv, p, Some t1, (S.subst (Cic.Rel 1) t2)
50       | t                       -> metasenv, p, None, t 
51    in
52    aux metasenv 0 context t
53
54 let skip_metas p =
55    let rec aux conts p =
56       if p <= 0 then conts else aux (T.id_tac :: conts) (pred p) 
57    in
58    aux [] p
59    
60 let get_conclusion context t =
61    let rec aux p context = function 
62       | Cic.Prod (name, t1, t2)  -> 
63          aux (succ p) (Some (name, Cic.Decl t1) :: context) t2
64       | Cic.LetIn (name, u1, t2) -> 
65          aux (succ p) (Some (name, Cic.Def (u1, None)) :: context) t2
66      | Cic.Cast (t2, t1)         -> aux p context t2
67      | t                         -> p, context, t
68    in aux 0 context t
69
70 let get_conclusion_dependences context t =
71    let p, context, conclusion = get_conclusion context t in
72    let rec aux l q = 
73       if q <= 0 then l else 
74       let b = TC.does_not_occur context (pred q) q conclusion in
75       aux (b :: l) (pred q)
76    in
77    aux [] p
78
79 let solve_independents ?with_what deps =
80   let rec aux p conts = function
81      | []          -> p, conts
82      | true :: tl  -> 
83         let cont = PT.apply_tac ~term:(Cic.Rel (succ p)) in
84         aux (succ p) (cont :: conts) tl
85      | false :: tl -> aux (succ p) conts tl
86    in 
87    let p, conts = aux 0 [] deps in
88    match with_what with
89       | None   -> conts
90       | Some t -> PT.apply_tac ~term:(S.lift p t) :: conts
91          
92 let lapply_tac ?(mk_fresh_name_callback = FreshNamesGenerator.mk_fresh_name ~subst:[]) 
93                (* ?(substs = []) *) ?to_what what =
94    let cut_tac term = PT.cut_tac ~mk_fresh_name_callback term in
95    let intros_tac () = PT.intros_tac ~mk_fresh_name_callback () in
96    let solve_conclusion_tac ?with_what p deps = 
97       T.then_ ~start:(intros_tac ())
98               ~continuation:(  
99          T.thens ~start:(PT.apply_tac what)
100                  ~continuations:( 
101             skip_metas p @ solve_independents ?with_what deps 
102          )
103       )
104    in
105    let lapply_tac (proof, goal) =
106       let xuri, metasenv, u, t = proof in
107       let _, context, _ = CicUtil.lookup_meta goal metasenv in
108       let lemma, _ = TC.type_of_aux' metasenv context what U.empty_ugraph in
109       match strip_dependent_prods metasenv context lemma with
110          | metasenv, p, Some premise, conclusion ->
111             let deps = get_conclusion_dependences context conclusion in
112             let inner_tac = match to_what with
113                | None      -> 
114                   T.thens ~start:(cut_tac premise)
115                           ~continuations:[
116                      solve_conclusion_tac ~with_what:(Cic.Rel 1) p deps;
117                      T.id_tac
118                   ]
119                | Some with_what -> 
120                   solve_conclusion_tac ~with_what p deps
121             in      
122             let outer_tac =
123                T.thens ~start:(cut_tac conclusion)
124                        ~continuations:[T.id_tac; inner_tac]
125             in
126             let status = (xuri, metasenv, u, t), goal in
127             PET.apply_tactic outer_tac status
128          | metasenv, p, None, conclusion         ->
129             failwith "lapply_tac: not implemented"
130    in
131    PET.mk_tactic lapply_tac
132    
133 (* fwd **********************************************************************)
134
135 let fwd_simpl_tac ~what ~dbd =
136    let fwd_simpl_tac status =
137       let (proof, goal) = status in
138       let _, metasenv, _, _ = proof in
139       let _, context, ty = CicUtil.lookup_meta goal metasenv in
140       let major, _ = TC.type_of_aux' metasenv context what U.empty_ugraph in 
141       match MetadataQuery.fwd_simpl ~dbd major with
142          | []       -> error fail_msg1
143          | uri :: _ -> prerr_endline (UriManager.string_of_uri uri); (proof, [])  
144    in
145    PET.mk_tactic fwd_simpl_tac