X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Fsoftware%2Fcomponents%2Ftactics%2Finversion_principle.ml;h=ae0a481862797155d34e48db7d3ebdc5608b0581;hb=59224cfec9e4037f4c2183c56625f06eb747fe9f;hp=b16b133bac997364592db469ef3f8df0d77bd3cd;hpb=fc4cf455977934bd737c3d6c8675ef7663a6a588;p=helm.git diff --git a/helm/software/components/tactics/inversion_principle.ml b/helm/software/components/tactics/inversion_principle.ml index b16b133ba..ae0a48186 100644 --- a/helm/software/components/tactics/inversion_principle.ml +++ b/helm/software/components/tactics/inversion_principle.ml @@ -8,7 +8,7 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. -* + * * HELM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -129,74 +129,103 @@ let rec build_theorem rightparam_tys arity_l (*arity_l only to name p's*) [(Cic.Rel 1)] uri typeno ) ;; -let build_inversion uri obj = - (*uri e obj of InductiveDefinition *) - let module PET = ProofEngineTypes in - let typeno = 0 in - let name,nleft,arity,cons_list = - match obj with - Cic.InductiveDefinition (tys,_,nleft,_) -> - let (name,_,arity,cons_list) = List.nth tys typeno in - (*we suppose there is only one inductiveType, so typeno=0 identically *) - (name,nleft,arity,cons_list) - |_ -> assert false - in - (*check if there are right parameters, else return void*) - if List.length (list_of_prod arity) = (nleft + 1) then - None - else - begin - let arity_l = cut_last (list_of_prod arity) in - let rightparam_tys = cut_first nleft arity_l in - let theorem = build_theorem rightparam_tys arity_l arity cons_list - [](*created_vars*) [](*created_vars_ty*) nleft uri typeno in - (*DEBUG*) debug_print (lazy ("theorem prima di refine: " ^ (CicPp.ppterm - theorem))); - let (ref_theorem,_,metasenv,_) = CicRefine.type_of_aux' [] [] theorem - CicUniv.empty_ugraph in - (*DEBUG*) debug_print (lazy ("theorem dopo refine: " ^ (CicPp.ppterm - ref_theorem))); - let buri = UriManager.buri_of_uri uri in - let inversor_uri = - UriManager.uri_of_string (buri ^ "/" ^ name ^ "_inv" ^ ".con") in - let goal = CicMkImplicit.new_meta metasenv [] in - let metasenv' = (goal,[],ref_theorem)::metasenv in - let proof= (Some inversor_uri,metasenv',Cic.Meta(goal,[]),ref_theorem) in - let _,applies = - List.fold_right - (fun _ (i,applies) -> - i+1,PrimitiveTactics.apply_tac (Cic.Rel i)::applies) - cons_list (2,[]) - in - let proof1,gl1 = - PET.apply_tactic - (Tacticals.then_ - ~start:(PrimitiveTactics.intros_tac ()) - (*if the number of applies is 1, we cannot use thens, but then_*) - ~continuation: - (match (List.length applies) with - 0 -> (Inversion.private_inversion_tac (Cic.Rel 1)) - | 1 -> (Tacticals.then_ - ~start:(Inversion.private_inversion_tac (Cic.Rel 1)) - ~continuation:(PrimitiveTactics.apply_tac (Cic.Rel 2)) - ) - | _ -> (Tacticals.thens - ~start:(Inversion.private_inversion_tac (Cic.Rel 1)) - ~continuations:applies - ) - )) - (proof,goal) - in - let metasenv,bo,ty = - match proof1 with (_,metasenv,bo,ty) -> metasenv,bo,ty - in - assert (metasenv = []); - Some - (inversor_uri, - Cic.Constant (UriManager.name_of_uri inversor_uri,Some bo,ty,[],[])) - end +let build_inversion ~add_obj ~add_coercion uri obj = + match obj with + | Cic.InductiveDefinition (tys,_,nleft,attrs) -> + let _,inductive,_,_ = List.hd tys in + if not inductive then [] + else + let build_one typeno name nleft arity cons_list = + (*check if there are right parameters, else return void*) + if List.length (list_of_prod arity) = (nleft + 1) then + None + else + try + let arity_l = cut_last (list_of_prod arity) in + let rightparam_tys = cut_first nleft arity_l in + let theorem = build_theorem rightparam_tys arity_l arity cons_list + [](*created_vars*) [](*created_vars_ty*) nleft uri typeno in + debug_print + (lazy ("theorem prima di refine: " ^ (CicPp.ppterm theorem))); + let (ref_theorem,_,metasenv,_) = + CicRefine.type_of_aux' [] [] theorem CicUniv.oblivion_ugraph in + (*DEBUG*) debug_print + (lazy ("theorem dopo refine: " ^ (CicPp.ppterm ref_theorem))); + let buri = UriManager.buri_of_uri uri in + let inversor_uri = + UriManager.uri_of_string (buri ^ "/" ^ name ^ "_inv" ^ ".con") in + let goal = CicMkImplicit.new_meta metasenv [] in + let metasenv' = (goal,[],ref_theorem)::metasenv in + let attrs = [`Class (`InversionPrinciple); `Generated] in + let _subst = [] in + let proof= + Some inversor_uri,metasenv',_subst, + lazy (Cic.Meta(goal,[])),ref_theorem, attrs in + let _,applies = + List.fold_right + (fun _ (i,applies) -> + i+1,PrimitiveTactics.apply_tac (Cic.Rel i)::applies + ) cons_list (2,[]) in + let proof1,gl1 = + ProofEngineTypes.apply_tactic + (Tacticals.then_ + ~start:(PrimitiveTactics.intros_tac ()) + (*if the number of applies is 1, we cannot use + thens, but then_*) + ~continuation: + (match List.length applies with + 0 -> Inversion.private_inversion_tac (Cic.Rel 1) + | 1 -> + Tacticals.then_ + ~start:(Inversion.private_inversion_tac (Cic.Rel 1)) + ~continuation:(PrimitiveTactics.apply_tac (Cic.Rel 2)) + | _ -> + Tacticals.thens + ~start:(Inversion.private_inversion_tac (Cic.Rel 1)) + ~continuations:applies)) + (proof,goal) in + let _,metasenv,_subst,bo,ty, attrs = proof1 in + assert (metasenv = []); + Some + (inversor_uri, + Cic.Constant + (UriManager.name_of_uri inversor_uri,Some (Lazy.force bo),ty,[],[])) + with + Inversion.EqualityNotDefinedYet -> + HLog.warn "No default equality, no inversion principle"; + None + | CicRefine.RefineFailure ls -> + HLog.warn + ("CicRefine.RefineFailure during generation of inversion principle: " ^ + Lazy.force ls) ; + None + | CicRefine.Uncertain ls -> + HLog.warn + ("CicRefine.Uncertain during generation of inversion principle: " ^ + Lazy.force ls) ; + None + | CicRefine.AssertFailure ls -> + HLog.warn + ("CicRefine.AssertFailure during generation of inversion principle: " ^ + Lazy.force ls) ; + None + in + let counter = ref (List.length tys) in + let all_inverters = + List.fold_right + (fun (name,_,arity,cons_list) res -> + counter := !counter-1; + match build_one !counter name nleft arity cons_list with + None -> res + | Some inv -> inv::res + ) tys [] + in + List.fold_left + (fun lemmas (uri,obj) -> add_obj uri obj @ uri :: lemmas + ) [] all_inverters + | _ -> [] ;; -let init () = ();; -LibrarySync.build_inversion_principle := build_inversion;; +let init () = + LibrarySync.add_object_declaration_hook build_inversion;;