1 (* Copyright (C) 2002, HELM Team.
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.
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.
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.
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,
22 * For details, see the HELM World-Wide-Web page,
23 * http://cs.unibo.it/helm/.
28 fun msg -> if debug then prerr_endline (Lazy.force msg) else ()
30 (* cuts away the last element of a list 'l' *)
33 | hd::tl when tl != [] -> hd:: (cut_last tl)
37 (* cuts away the first 'n' elements of a list 'l' *)
38 let rec cut_first n l =
41 | hd::tl -> cut_first (n-1) tl
46 (* returns the first 'n' elements of a list 'l' *)
47 let rec takefirst n l =
50 hd::tl when n > 0 -> hd:: takefirst (n-1) tl
55 (* from a complex Cic.Prod term, returns the list of its components *)
56 let rec list_of_prod term =
58 | Cic.Prod (_,src,tgt) -> src::(list_of_prod tgt)
62 let rec build_metas sort cons_list created_vars right_created_vars prop
70 (List.map (CicSubstitution.lift 1) created_vars)
71 (List.map (CicSubstitution.lift 1) right_created_vars)
72 (List.map (CicSubstitution.lift 1) prop) uri typeno)
75 Cic.Name("H"), (*new name?*)
76 Cic.Appl([Cic.MutInd(uri, typeno, [])] @ created_vars),
77 Cic.Appl (( (List.map (CicSubstitution.lift 1) prop) @
78 (List.map (CicSubstitution.lift 1 ) right_created_vars) @
79 (if Inversion.isSetType sort then [Cic.Rel 1] else [])(*H*))
83 (* computes the type of the abstract P *)
84 let rec get_prop_arity sort rightparam_tys(*only to name m's*) created_vars_ty
85 local_rvars left_created_vars nleft uri typeno =
86 match (created_vars_ty) with
87 hd::tl when (nleft > 0) ->
88 get_prop_arity sort rightparam_tys tl local_rvars left_created_vars
92 Cic.Name("m" ^ string_of_int(List.length rightparam_tys) ),
94 get_prop_arity sort (List.tl rightparam_tys)
95 (List.map (CicSubstitution.lift 1) tl)
96 (List.map (CicSubstitution.lift 1) (local_rvars @ [Cic.Rel 1]))
97 (List.map (CicSubstitution.lift 1) left_created_vars) nleft uri typeno
100 if Inversion.isSetType sort then
101 Cic.Prod(Cic.Anonymous,
102 Cic.Appl([Cic.MutInd(uri, typeno, [])]
103 @ (List.map (CicSubstitution.lift (-1)) left_created_vars)
104 @ (List.map (CicSubstitution.lift(-1)) local_rvars) ),
110 (* created vars is empty at the beginning *)
111 let rec build_theorem rightparam_tys arity_l (*arity_l only to name p's*)
112 arity cons_list created_vars created_vars_ty nleft
115 Cic.Prod(_,src,tgt) ->
117 Cic.Name("p" ^ string_of_int(List.length arity_l)),
119 build_theorem rightparam_tys
120 (List.tl arity_l) tgt cons_list
121 (List.map (CicSubstitution.lift 1) (created_vars @ [Cic.Rel 1]))
122 (List.map (CicSubstitution.lift 1) (created_vars_ty @ [src]))
125 Cic.Prod(Cic.Name("P"),
126 get_prop_arity sort rightparam_tys created_vars_ty [](*local vars*)
127 (takefirst nleft created_vars) (*left_created_vars*) nleft uri typeno,
128 build_metas sort cons_list created_vars (cut_first nleft created_vars)
129 [(Cic.Rel 1)] uri typeno )
132 let build_inversion uri obj =
133 (*uri e obj of InductiveDefinition *)
134 let module PET = ProofEngineTypes in
135 let build_one typeno name nleft arity cons_list =
136 (*check if there are right parameters, else return void*)
137 if List.length (list_of_prod arity) = (nleft + 1) then
141 let arity_l = cut_last (list_of_prod arity) in
142 let rightparam_tys = cut_first nleft arity_l in
143 let theorem = build_theorem rightparam_tys arity_l arity cons_list
144 [](*created_vars*) [](*created_vars_ty*) nleft uri typeno in
146 (lazy ("theorem prima di refine: " ^ (CicPp.ppterm theorem)));
147 let (ref_theorem,_,metasenv,_) = CicRefine.type_of_aux' [] [] theorem
148 CicUniv.empty_ugraph in
149 (*DEBUG*) debug_print
150 (lazy ("theorem dopo refine: " ^ (CicPp.ppterm ref_theorem)));
151 let buri = UriManager.buri_of_uri uri in
153 UriManager.uri_of_string (buri ^ "/" ^ name ^ "_inv" ^ ".con") in
154 let goal = CicMkImplicit.new_meta metasenv [] in
155 let metasenv' = (goal,[],ref_theorem)::metasenv in
157 (Some inversor_uri,metasenv',Cic.Meta(goal,[]),ref_theorem) in
160 (fun _ (i,applies) ->
161 i+1,PrimitiveTactics.apply_tac (Cic.Rel i)::applies)
167 ~start:(PrimitiveTactics.intros_tac ())
168 (*if the number of applies is 1, we cannot use
171 (match (List.length applies) with
172 0 -> (Inversion.private_inversion_tac (Cic.Rel 1))
173 | 1 -> (Tacticals.then_
174 ~start:(Inversion.private_inversion_tac
176 ~continuation:(PrimitiveTactics.apply_tac
179 | _ -> (Tacticals.thens
180 ~start:(Inversion.private_inversion_tac
182 ~continuations:applies
188 match proof1 with (_,metasenv,bo,ty) -> metasenv,bo,ty
190 assert (metasenv = []);
194 (UriManager.name_of_uri inversor_uri,Some bo,ty,[],[]))
196 Inversion.EqualityNotDefinedYet -> None
199 | Cic.InductiveDefinition (tys,_,nleft,_) ->
200 let counter = ref (List.length tys) in
202 (fun (name,_,arity,cons_list) res ->
203 counter := !counter-1;
204 match build_one !counter name nleft arity cons_list with
206 | Some inv -> inv::res)
214 LibrarySync.build_inversion_principle := build_inversion;;