X-Git-Url: http://matita.cs.unibo.it/gitweb/?a=blobdiff_plain;f=helm%2Focaml%2Ftactics%2Fring.ml;h=1d7cc10e6bfad0a0a16fe9b7ad2b74bc0dc6d078;hb=97c2d258a5c524eb5c4b85208899d80751a2c82f;hp=e2de0459193e91339b562f4f3a27075781585d78;hpb=a6fc115fd7d4cfba94a43f001f4c27322d3db1a8;p=helm.git diff --git a/helm/ocaml/tactics/ring.ml b/helm/ocaml/tactics/ring.ml index e2de04591..1d7cc10e6 100644 --- a/helm/ocaml/tactics/ring.ml +++ b/helm/ocaml/tactics/ring.ml @@ -28,17 +28,14 @@ open PrimitiveTactics open ProofEngineTypes open UriManager -open HelmLibraryObjects - (** DEBUGGING *) (** perform debugging output? *) let debug = false +let debug_print = fun _ -> () (** debugging print *) -let warn s = - if debug then - prerr_endline ("RING WARNING: " ^ s) +let warn s = debug_print (lazy ("RING WARNING: " ^ (Lazy.force s))) (** CIC URIS *) @@ -191,19 +188,19 @@ exception GoalUnringable *) let ringable = let is_equality = function - | Cic.MutInd (uri, 0, []) when (eq uri Logic.eq_URI) -> true + | Cic.MutInd (uri, 0, []) when (eq uri HelmLibraryObjects.Logic.eq_URI) -> true | _ -> false in let is_real = function - | Cic.Const (uri, _) when (eq uri Reals.r_URI) -> true + | Cic.Const (uri, _) when (eq uri HelmLibraryObjects.Reals.r_URI) -> true | _ -> false in function | Cic.Appl (app::set::_::_::[]) when (is_equality app && is_real set) -> - warn "Goal Ringable!"; + warn (lazy "Goal Ringable!"); true | _ -> - warn "Goal Not Ringable :-(("; + warn (lazy "Goal Not Ringable :-(("); false (** @@ -215,8 +212,8 @@ let ringable = *) let split_eq = function | (Cic.Appl (_::_::t1::t2::[])) as term when ringable term -> - warn ("" ^ (CicPp.ppterm t1) ^ ""); - warn ("" ^ (CicPp.ppterm t2) ^ ""); + warn (lazy ("" ^ (CicPp.ppterm t1) ^ "")); + warn (lazy ("" ^ (CicPp.ppterm t2) ^ "")); (t1, t2) | _ -> raise GoalUnringable @@ -253,7 +250,7 @@ let path_of_int n = @return a cic term representing the variable map containing vars variables *) let btree_of_array ~vars = - let r = Reals.r in + let r = HelmLibraryObjects.Reals.r in let empty_vm_r = mkCtor empty_vm_uri [quote_varmap_A_uri,r] in let node_vm_r = mkCtor node_vm_uri [quote_varmap_A_uri,r] in let size = Array.length vars in @@ -286,17 +283,17 @@ let abstract_poly ~terms = let rec aux = function (* TODO not tail recursive *) (* "bop" -> binary operator | "uop" -> unary operator *) | Cic.Appl (bop::t1::t2::[]) - when (cic_is_const ~uri:(Some Reals.rplus_URI) bop) -> (* +. *) + when (cic_is_const ~uri:(Some HelmLibraryObjects.Reals.rplus_URI) bop) -> (* +. *) Cic.Appl [mkCtor applus_uri []; aux t1; aux t2] | Cic.Appl (bop::t1::t2::[]) - when (cic_is_const ~uri:(Some Reals.rmult_URI) bop) -> (* *. *) + when (cic_is_const ~uri:(Some HelmLibraryObjects.Reals.rmult_URI) bop) -> (* *. *) Cic.Appl [mkCtor apmult_uri []; aux t1; aux t2] | Cic.Appl (uop::t::[]) - when (cic_is_const ~uri:(Some Reals.ropp_URI) uop) -> (* ~-. *) + when (cic_is_const ~uri:(Some HelmLibraryObjects.Reals.ropp_URI) uop) -> (* ~-. *) Cic.Appl [mkCtor apopp_uri []; aux t] - | t when (cic_is_const ~uri:(Some Reals.r0_URI) t) -> (* 0. *) + | t when (cic_is_const ~uri:(Some HelmLibraryObjects.Reals.r0_URI) t) -> (* 0. *) mkCtor ap0_uri [] - | t when (cic_is_const ~uri:(Some Reals.r1_URI) t) -> (* 1. *) + | t when (cic_is_const ~uri:(Some HelmLibraryObjects.Reals.r1_URI) t) -> (* 1. *) mkCtor ap1_uri [] | t -> (* variable *) try @@ -327,20 +324,20 @@ let abstract_poly ~terms = *) let build_segments ~terms = let theory_args_subst varmap = - [abstract_rings_A_uri, Reals.r ; - abstract_rings_Aplus_uri, Reals.rplus ; - abstract_rings_Amult_uri, Reals.rmult ; - abstract_rings_Aone_uri, Reals.r1 ; - abstract_rings_Azero_uri, Reals.r0 ; - abstract_rings_Aopp_uri, Reals.ropp ; + [abstract_rings_A_uri, HelmLibraryObjects.Reals.r ; + abstract_rings_Aplus_uri, HelmLibraryObjects.Reals.rplus ; + abstract_rings_Amult_uri, HelmLibraryObjects.Reals.rmult ; + abstract_rings_Aone_uri, HelmLibraryObjects.Reals.r1 ; + abstract_rings_Azero_uri, HelmLibraryObjects.Reals.r0 ; + abstract_rings_Aopp_uri, HelmLibraryObjects.Reals.ropp ; abstract_rings_vm_uri, varmap] in let theory_args_subst' eq varmap t = - [abstract_rings_A_uri, Reals.r ; - abstract_rings_Aplus_uri, Reals.rplus ; - abstract_rings_Amult_uri, Reals.rmult ; - abstract_rings_Aone_uri, Reals.r1 ; - abstract_rings_Azero_uri, Reals.r0 ; - abstract_rings_Aopp_uri, Reals.ropp ; + [abstract_rings_A_uri, HelmLibraryObjects.Reals.r ; + abstract_rings_Aplus_uri, HelmLibraryObjects.Reals.rplus ; + abstract_rings_Amult_uri, HelmLibraryObjects.Reals.rmult ; + abstract_rings_Aone_uri, HelmLibraryObjects.Reals.r1 ; + abstract_rings_Azero_uri, HelmLibraryObjects.Reals.r0 ; + abstract_rings_Aopp_uri, HelmLibraryObjects.Reals.ropp ; abstract_rings_Aeq_uri, eq ; abstract_rings_vm_uri, varmap ; abstract_rings_T_uri, t] in @@ -352,8 +349,8 @@ let build_segments ~terms = let apolynomial_normalize_ok eq varmap t = mkConst apolynomial_normalize_ok_uri (theory_args_subst' eq varmap t) in let lxy_false = (** Cic funcion "fun (x,y):R -> false" *) - Cic.Lambda (Cic.Anonymous, Reals.r, - Cic.Lambda (Cic.Anonymous, Reals.r, Datatypes.falseb)) + Cic.Lambda (Cic.Anonymous, HelmLibraryObjects.Reals.r, + Cic.Lambda (Cic.Anonymous, HelmLibraryObjects.Reals.r, HelmLibraryObjects.Datatypes.falseb)) in let (aterms, varmap) = abstract_poly ~terms in (* abstract polys *) List.map (* build ring segments *) @@ -361,7 +358,7 @@ let build_segments ~terms = Cic.Appl [interp_ap varmap ; t], Cic.Appl ( [interp_sacs varmap ; Cic.Appl [apolynomial_normalize; t]]), - Cic.Appl [apolynomial_normalize_ok lxy_false varmap Reals.rtheory ; t] + Cic.Appl [apolynomial_normalize_ok lxy_false varmap HelmLibraryObjects.Reals.rtheory ; t] ) aterms @@ -369,7 +366,7 @@ let status_of_single_goal_tactic_result = function proof,[goal] -> proof,goal | _ -> - raise (Fail "status_of_single_goal_tactic_result: the tactic did not produce exactly a new goal") + raise (Fail (lazy "status_of_single_goal_tactic_result: the tactic did not produce exactly a new goal")) (* Galla: spostata in variousTactics.ml (** @@ -378,7 +375,7 @@ let status_of_single_goal_tactic_result = @param term term to cut *) let elim_type_tac ~term status = - warn "in Ring.elim_type_tac"; + warn (lazy "in Ring.elim_type_tac"); Tacticals.thens ~start:(cut_tac ~term) ~continuations:[elim_simpl_intros_tac ~term:(Cic.Rel 1) ; Tacticals.id_tac] status *) @@ -389,11 +386,16 @@ let elim_type_tac ~term status = @param term term to cut @param proof term used to prove second subgoal generated by elim_type *) -let elim_type2_tac ~term ~proof status = +(* FG: METTERE I NOMI ANCHE QUI? *) +let elim_type2_tac ~term ~proof = + let elim_type2_tac ~term ~proof status = let module E = EliminationTactics in - warn "in Ring.elim_type2"; - Tacticals.thens ~start:(E.elim_type_tac ~term) - ~continuations:[Tacticals.id_tac ; exact_tac ~term:proof] status + warn (lazy "in Ring.elim_type2"); + ProofEngineTypes.apply_tactic + (Tacticals.thens ~start:(E.elim_type_tac term) + ~continuations:[Tacticals.id_tac ; exact_tac ~term:proof]) status + in + ProofEngineTypes.mk_tactic (elim_type2_tac ~term ~proof) (* Galla: spostata in variousTactics.ml (** @@ -403,7 +405,7 @@ let elim_type2_tac ~term ~proof status = @param status current proof engine status *) let reflexivity_tac (proof, goal) = - warn "in Ring.reflexivity_tac"; + warn (lazy "in Ring.reflexivity_tac"); let refl_eqt = mkCtor ~uri:refl_eqt_uri ~exp_named_subst:[] in try apply_tac (proof, goal) ~term:refl_eqt @@ -423,7 +425,8 @@ let lift ~n (a,b,c,d,e,f,g,h) = @param count number of hypotheses to remove @param status current proof engine status *) -let purge_hyps_tac ~count status = +let purge_hyps_tac ~count = + let purge_hyps_tac ~count status = let module S = ProofEngineStructuralRules in let (proof, goal) = status in let rec aux n context status = @@ -431,8 +434,15 @@ let purge_hyps_tac ~count status = match (n, context) with | (0, _) -> status | (n, hd::tl) -> - aux (n-1) tl - (status_of_single_goal_tactic_result (S.clear ~hyp:hd status)) + let name_of_hyp = + match hd with + None + | Some (Cic.Anonymous,_) -> assert false + | Some (Cic.Name name,_) -> name + in + aux (n-1) tl + (status_of_single_goal_tactic_result + (ProofEngineTypes.apply_tactic (S.clear ~hyp:name_of_hyp) status)) | (_, []) -> failwith "Ring.purge_hyps_tac: no hypotheses left" in let (_, metasenv, _, _) = proof in @@ -440,6 +450,8 @@ let purge_hyps_tac ~count status = let proof',goal' = aux count context status in assert (goal = goal') ; proof',[goal'] + in + ProofEngineTypes.mk_tactic (purge_hyps_tac ~count) (** THE TACTIC! *) @@ -447,19 +459,21 @@ let purge_hyps_tac ~count status = Ring tactic, does associative and commutative rewritings in Reals ring @param status current proof engine status *) + let ring_tac status = let (proof, goal) = status in - warn "in Ring tactic"; - let eqt = mkMutInd (Logic.eq_URI, 0) [] in - let r = Reals.r in + warn (lazy "in Ring tactic"); + let eqt = mkMutInd (HelmLibraryObjects.Logic.eq_URI, 0) [] in + let r = HelmLibraryObjects.Reals.r in let metasenv = metasenv_of_status status in let (metano, context, ty) = CicUtil.lookup_meta goal metasenv in let (t1, t2) = split_eq ty in (* goal like t1 = t2 *) match (build_segments ~terms:[t1; t2]) with | (t1', t1'', t1'_eq_t1'')::(t2', t2'', t2'_eq_t2'')::[] -> begin + if debug then List.iter (* debugging, feel free to remove *) (fun (descr, term) -> - warn (descr ^ " " ^ (CicPp.ppterm term))) + warn (lazy (descr ^ " " ^ (CicPp.ppterm term)))) (List.combine ["t1"; "t1'"; "t1''"; "t1'_eq_t1''"; "t2"; "t2'"; "t2''"; "t2'_eq_t2''"] @@ -467,8 +481,8 @@ let ring_tac status = t2; t2'; t2''; t2'_eq_t2'']); try let new_hyps = ref 0 in (* number of new hypotheses created *) - Tacticals.try_tactics - status + ProofEngineTypes.apply_tactic + (Tacticals.first ~tactics:[ "reflexivity", EqualityTactics.reflexivity_tac ; "exact t1'_eq_t1''", exact_tac ~term:t1'_eq_t1'' ; @@ -476,29 +490,33 @@ let ring_tac status = "exact sym_eqt su t1 ...", exact_tac ~term:( Cic.Appl - [mkConst Logic.sym_eq_URI - [equality_is_a_congruence_A, Reals.r; + [mkConst HelmLibraryObjects.Logic.sym_eq_URI + [equality_is_a_congruence_A, HelmLibraryObjects.Reals.r; equality_is_a_congruence_x, t1'' ; equality_is_a_congruence_y, t1 ] ; t1'_eq_t1'' ]) ; - "elim_type eqt su t1 ...", (fun status -> + "elim_type eqt su t1 ...", ProofEngineTypes.mk_tactic (fun status -> let status' = (* status after 1st elim_type use *) let context = context_of_status status in - if not (are_convertible context t1'' t1) then begin - warn "t1'' and t1 are NOT CONVERTIBLE"; + let b,_ = (*TASSI : FIXME*) + are_convertible context t1'' t1 CicUniv.empty_ugraph in + if not b then begin + warn (lazy "t1'' and t1 are NOT CONVERTIBLE"); let newstatus = - elim_type2_tac (* 1st elim_type use *) - status ~proof:t1'_eq_t1'' - ~term:(Cic.Appl [eqt; r; t1''; t1]) + ProofEngineTypes.apply_tactic + (elim_type2_tac (* 1st elim_type use *) + ~proof:t1'_eq_t1'' + ~term:(Cic.Appl [eqt; r; t1''; t1])) + status in incr new_hyps; (* elim_type add an hyp *) match newstatus with (proof,[goal]) -> proof,goal | _ -> assert false end else begin - warn "t1'' and t1 are CONVERTIBLE"; + warn (lazy "t1'' and t1 are CONVERTIBLE"); status end in @@ -506,58 +524,71 @@ let ring_tac status = lift 1 (t1,t1',t1'',t1'_eq_t1'', t2,t2',t2'',t2'_eq_t2'') in let status'' = - Tacticals.try_tactics (* try to solve 1st subgoal *) - status' + ProofEngineTypes.apply_tactic + (Tacticals.first (* try to solve 1st subgoal *) ~tactics:[ "exact t2'_eq_t2''", exact_tac ~term:t2'_eq_t2''; "exact sym_eqt su t2 ...", exact_tac ~term:( Cic.Appl - [mkConst Logic.sym_eq_URI - [equality_is_a_congruence_A, Reals.r; + [mkConst HelmLibraryObjects.Logic.sym_eq_URI + [equality_is_a_congruence_A, HelmLibraryObjects.Reals.r; equality_is_a_congruence_x, t2'' ; equality_is_a_congruence_y, t2 ] ; t2'_eq_t2'' ]) ; - "elim_type eqt su t2 ...", (fun status -> + "elim_type eqt su t2 ...", + ProofEngineTypes.mk_tactic (fun status -> let status' = let context = context_of_status status in - if not (are_convertible context t2'' t2) then begin - warn "t2'' and t2 are NOT CONVERTIBLE"; + let b,_ = (* TASSI:FIXME *) + are_convertible context t2'' t2 CicUniv.empty_ugraph + in + if not b then begin + warn (lazy "t2'' and t2 are NOT CONVERTIBLE"); let newstatus = - elim_type2_tac (* 2nd elim_type use *) - status ~proof:t2'_eq_t2'' - ~term:(Cic.Appl [eqt; r; t2''; t2]) + ProofEngineTypes.apply_tactic + (elim_type2_tac (* 2nd elim_type use *) + ~proof:t2'_eq_t2'' + ~term:(Cic.Appl [eqt; r; t2''; t2])) + status in incr new_hyps; (* elim_type add an hyp *) match newstatus with (proof,[goal]) -> proof,goal | _ -> assert false end else begin - warn "t2'' and t2 are CONVERTIBLE"; + warn (lazy "t2'' and t2 are CONVERTIBLE"); status end in try (* try to solve main goal *) - warn "trying reflexivity ...."; - EqualityTactics.reflexivity_tac status' + warn (lazy "trying reflexivity ...."); + ProofEngineTypes.apply_tactic + EqualityTactics.reflexivity_tac status' with (Fail _) -> (* leave conclusion to the user *) - warn "reflexivity failed, solution's left as an ex :-)"; - purge_hyps_tac ~count:!new_hyps status')] + warn (lazy "reflexivity failed, solution's left as an ex :-)"); + ProofEngineTypes.apply_tactic + (purge_hyps_tac ~count:!new_hyps) status')]) + status' in - status'')] + status'')]) + status with (Fail s) -> - raise (Fail ("Ring failure: " ^ s)) + raise (Fail (lazy ("Ring failure: " ^ Lazy.force s))) end | _ -> (* impossible: we are applying ring exacty to 2 terms *) assert false (* wrap ring_tac catching GoalUnringable and raising Fail *) + let ring_tac status = try ring_tac status with GoalUnringable -> - raise (Fail "goal unringable") + raise (Fail (lazy "goal unringable")) + +let ring_tac = ProofEngineTypes.mk_tactic ring_tac