aboutsummaryrefslogtreecommitdiffhomepage
path: root/tactics/equality.ml
diff options
context:
space:
mode:
Diffstat (limited to 'tactics/equality.ml')
-rw-r--r--tactics/equality.ml148
1 files changed, 85 insertions, 63 deletions
diff --git a/tactics/equality.ml b/tactics/equality.ml
index f907b1fd7..3bfc719e2 100644
--- a/tactics/equality.ml
+++ b/tactics/equality.ml
@@ -40,6 +40,9 @@ open Vernacexpr
open Setoid_replace
open Declarations
open Indrec
+open Printer
+open Clenv
+open Clenvtac
(* Rewriting tactics *)
@@ -550,66 +553,84 @@ exception NotDiscriminable
let eq_baseid = id_of_string "e"
-let discr_positions env sigma (lbeq,(t,t1,t2)) id cpath dirn sort =
+let apply_on_clause (f,t) clause =
+ let sigma = Evd.evars_of clause.evd in
+ let f_clause = mk_clenv_from_env clause.env sigma None (f,t) in
+ let argmv =
+ (match kind_of_term (last_arg f_clause.templval.Evd.rebus) with
+ | Meta mv -> mv
+ | _ -> errorlabstrm "" (str "Ill-formed clause applicator")) in
+ clenv_fchain argmv f_clause clause
+
+let discr_positions env sigma (lbeq,(t,t1,t2)) eq_clause cpath dirn sort =
let e = next_ident_away eq_baseid (ids_of_context env) in
let e_env = push_named (e,None,t) env in
+ let eqn = mkApp(lbeq.eq,[|t;t1;t2|]) in
let discriminator =
build_discriminator sigma e_env dirn (mkVar e) sort cpath in
let (pf, absurd_term) = discrimination_pf e (t,t1,t2) discriminator lbeq in
- tclCOMPLETE
- ((tclTHENS (cut_intro absurd_term)
- [onLastHyp gen_absurdity;
- refine (mkApp (pf,[|mkVar id|]))]))
+ let pf_ty = mkArrow eqn absurd_term in
+ let absurd_clause = apply_on_clause (pf,pf_ty) eq_clause in
+ tclTHENS (cut_intro absurd_term)
+ [onLastHyp gen_absurdity; res_pf absurd_clause]
-let discrEq (lbeq,(t,t1,t2) as u) id gls =
- let sigma = project gls in
+let discrEq (lbeq,(t,t1,t2) as u) eq_clause gls =
+ let sigma = Evd.evars_of eq_clause.evd in
let env = pf_env gls in
match find_positions env sigma t1 t2 with
| Inr _ ->
- errorlabstrm "discr" (str" Not a discriminable equality")
+ errorlabstrm "discr" (str"Not a discriminable equality")
| Inl (cpath, (_,dirn), _) ->
let sort = pf_apply get_type_of gls (pf_concl gls) in
- discr_positions env sigma u id cpath dirn sort gls
-
-let onEquality tac id gls =
- let eqn = pf_whd_betadeltaiota gls (pf_get_hyp_typ gls id) in
+ discr_positions env sigma u eq_clause cpath dirn sort gls
+
+let onEquality with_evars tac (c,lbindc) gls =
+ let t = pf_type_of gls c in
+ let t' = try snd (pf_reduce_to_quantified_ind gls t) with UserError _ -> t in
+ let eq_clause = make_clenv_binding gls (c,t') lbindc in
+ let eq_clause' = clenv_pose_dependent_evars with_evars eq_clause in
+ let eqn = clenv_type eq_clause' in
let eq =
try find_eq_data_decompose eqn
with PatternMatchingFailure ->
- errorlabstrm "" (pr_id id ++ str": not a primitive equality")
- in tac eq id gls
+ errorlabstrm "" (str"No primitive equality found") in
+ tclTHEN
+ (Refiner.tclEVARS (Evd.evars_of eq_clause'.evd))
+ (tac eq eq_clause') gls
-let onNegatedEquality tac gls =
+let onNegatedEquality with_evars tac gls =
let ccl = pf_concl gls in
- let eq =
- try match kind_of_term (hnf_constr (pf_env gls) (project gls) ccl) with
- | Prod (_,t,u) when is_empty_type u ->
- find_eq_data_decompose (pf_whd_betadeltaiota gls t)
- | _ -> raise PatternMatchingFailure
- with PatternMatchingFailure ->
+ match kind_of_term (hnf_constr (pf_env gls) (project gls) ccl) with
+ | Prod (_,t,u) when is_empty_type u ->
+ tclTHEN introf
+ (onLastHyp (fun id ->
+ onEquality with_evars tac (mkVar id,NoBindings))) gls
+ | _ ->
errorlabstrm "" (str "Not a negated primitive equality")
- in tclTHEN introf (onLastHyp (tac eq)) gls
-let discrSimpleClause = function
- | None -> onNegatedEquality discrEq
- | Some ((_,id),_) -> onEquality discrEq id
+let discrSimpleClause with_evars = function
+ | None -> onNegatedEquality with_evars discrEq
+ | Some ((_,id),_) -> onEquality with_evars discrEq (mkVar id,NoBindings)
-let discr = onEquality discrEq
+let discr with_evars = onEquality with_evars discrEq
-let discrClause = onClauses discrSimpleClause
+let discrClause with_evars = onClauses (discrSimpleClause with_evars)
-let discrEverywhere =
+let discrEverywhere with_evars =
tclORELSE
- (Tacticals.tryAllClauses discrSimpleClause)
+ (tclTHEN
+ (tclREPEAT introf)
+ (Tacticals.tryAllHyps
+ (fun id -> tclCOMPLETE (discr with_evars (mkVar id,NoBindings)))))
(fun gls ->
errorlabstrm "DiscrEverywhere" (str"No discriminable equalities"))
-let discr_tac = function
- | None -> discrEverywhere
- | Some id -> try_intros_until discr id
+let discr_tac with_evars = function
+ | None -> discrEverywhere with_evars
+ | Some c -> onInductionArg (discr with_evars) c
-let discrConcl gls = discrClause onConcl gls
-let discrHyp id gls = discrClause (onHyp id) gls
+let discrConcl gls = discrClause false onConcl gls
+let discrHyp id gls = discrClause false (onHyp id) gls
(* returns the sigma type (sigS, sigT) with the respective
constructor depending on the sort *)
@@ -828,7 +849,7 @@ let simplify_args env sigma t =
| eq, [t1;c1;t2;c2] -> applist (eq,[t1;nf env sigma c1;t2;nf env sigma c2])
| _ -> t
-let inject_at_positions env sigma (eq,(t,t1,t2)) id posns =
+let inject_at_positions env sigma (eq,(t,t1,t2)) eq_clause posns =
let e = next_ident_away eq_baseid (ids_of_context env) in
let e_env = push_named (e,None,t) env in
let injectors =
@@ -837,9 +858,12 @@ let inject_at_positions env sigma (eq,(t,t1,t2)) id posns =
(* arbitrarily take t1' as the injector default value *)
let (injbody,resty) = build_injector sigma e_env t1' (mkVar e) cpath in
let injfun = mkNamedLambda e t injbody in
- let pf = applist(eq.congr,[t;resty;injfun;t1;t2;mkVar id]) in
- let ty = simplify_args env sigma (get_type_of env sigma pf) in
- (pf,ty))
+ let pf = applist(eq.congr,[t;resty;injfun;t1;t2]) in
+ let pf_typ = get_type_of env sigma pf in
+ let inj_clause = apply_on_clause (pf,pf_typ) eq_clause in
+ let pf = clenv_value_cast_meta inj_clause in
+ let ty = simplify_args env sigma (clenv_type inj_clause) in
+ (pf,ty))
posns in
if injectors = [] then
errorlabstrm "Equality.inj" (str "Failed to decompose the equality");
@@ -850,14 +874,13 @@ let inject_at_positions env sigma (eq,(t,t1,t2)) id posns =
exception Not_dep_pair
-let injEq ipats (eq,(t,t1,t2)) id gls =
- let sigma = project gls in
- let env = pf_env gls in
+let injEq ipats (eq,(t,t1,t2)) eq_clause =
+ let sigma = Evd.evars_of eq_clause.evd in
+ let env = eq_clause.env in
match find_positions env sigma t1 t2 with
| Inl _ ->
errorlabstrm "Inj"
- (str (string_of_id id) ++
- str" is not a projectable equality but a discriminable one")
+ (str"Not a projectable equality but a discriminable one")
| Inr [] ->
errorlabstrm "Equality.inj"
(str"Nothing to do, it is an equality between convertible terms")
@@ -895,45 +918,44 @@ let injEq ipats (eq,(t,t1,t2)) id gls =
[|ar1.(0);Ind_tables.find_eq_dec_proof ind;
ar1.(1);ar1.(2);ar1.(3);ar2.(3)|])
)) (Auto.trivial [] [])
- ] gls
+ ]
(* not a dep eq or no decidable type found *)
) else (raise Not_dep_pair)
- ) with _ -> (
- tclTHEN
- (inject_at_positions env sigma (eq,(t,t1,t2)) id posns)
+ ) with _ ->
+ tclTHEN
+ (inject_at_positions env sigma (eq,(t,t1,t2)) eq_clause posns)
(intros_pattern None ipats)
- gls
- )
-let inj ipats = onEquality (injEq ipats)
+let inj ipats with_evars = onEquality with_evars (injEq ipats)
-let injClause ipats = function
- | None -> onNegatedEquality (injEq ipats)
- | Some id -> try_intros_until (inj ipats) id
+let injClause ipats with_evars = function
+ | None -> onNegatedEquality with_evars (injEq ipats)
+ | Some c -> onInductionArg (inj ipats with_evars) c
-let injConcl gls = injClause [] None gls
-let injHyp id gls = injClause [] (Some id) gls
+let injConcl gls = injClause [] false None gls
+let injHyp id gls = injClause [] false (Some (ElimOnIdent (dummy_loc,id))) gls
-let decompEqThen ntac (lbeq,(t,t1,t2) as u) id gls =
+let decompEqThen ntac (lbeq,(t,t1,t2) as u) clause gls =
let sort = pf_apply get_type_of gls (pf_concl gls) in
- let sigma = project gls in
+ let sigma = Evd.evars_of clause.evd in
let env = pf_env gls in
match find_positions env sigma t1 t2 with
| Inl (cpath, (_,dirn), _) ->
- discr_positions env sigma u id cpath dirn sort gls
+ discr_positions env sigma u clause cpath dirn sort gls
| Inr [] -> (* Change: do not fail, simplify clear this trivial hyp *)
ntac 0 gls
| Inr posns ->
tclTHEN
- (inject_at_positions env sigma (lbeq,(t,t1,t2)) id (List.rev posns))
+ (inject_at_positions env sigma (lbeq,(t,t1,t2)) clause
+ (List.rev posns))
(ntac (List.length posns))
gls
-let dEqThen ntac = function
- | None -> onNegatedEquality (decompEqThen ntac)
- | Some id -> try_intros_until (onEquality (decompEqThen ntac)) id
+let dEqThen with_evars ntac = function
+ | None -> onNegatedEquality with_evars (decompEqThen ntac)
+ | Some c -> onInductionArg (onEquality with_evars (decompEqThen ntac)) c
-let dEq = dEqThen (fun x -> tclIDTAC)
+let dEq with_evars = dEqThen with_evars (fun x -> tclIDTAC)
let rewrite_msg = function
| None -> str "passed term is not a primitive equality"