aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Algebra.v79
-rw-r--r--src/Tactics/Nsatz.v3
-rw-r--r--src/Util/Tactics.v7
3 files changed, 73 insertions, 16 deletions
diff --git a/src/Algebra.v b/src/Algebra.v
index 99fb2deb8..7f4fe06cc 100644
--- a/src/Algebra.v
+++ b/src/Algebra.v
@@ -580,6 +580,10 @@ Ltac field_nonzero_mul_split :=
repeat match goal with
| [ H : ?R (?mul ?x ?y) ?zero |- _ ]
=> apply IntegralDomain.mul_nonzero_nonzero_cases in H; destruct H
+ | [ |- not (?R (?mul ?x ?y) ?zero) ]
+ => apply IntegralDomain.mul_nonzero_nonzero_iff; split
+ | [ H : not (?R (?mul ?x ?y) ?zero) |- _ ]
+ => apply IntegralDomain.mul_nonzero_nonzero_iff in H; destruct H
end.
Ltac common_denominator :=
@@ -607,6 +611,28 @@ Ltac common_denominator_all :=
repeat match goal with [H: _ |- _ _ _ ] => progress common_denominator_in H end.
(** Now we have more conservative versions that don't simplify non-division structure. *)
+Ltac deduplicate_nonfraction_pieces mul :=
+ repeat match goal with
+ | [ x0 := ?v, x1 := context[?v] |- _ ]
+ => progress change v with x0 in x1
+ | [ x := mul ?a ?b |- _ ]
+ => not is_var a;
+ let a' := fresh x in
+ pose a as a'; change a with a' in x
+ | [ x := mul ?a ?b |- _ ]
+ => not is_var b;
+ let b' := fresh x in
+ pose b as b'; change b with b' in x
+ | [ x0 := ?v, x1 := ?v |- _ ]
+ => change x1 with x0 in *; clear x1
+ | [ x := ?v |- _ ]
+ => is_var v; subst x
+ | [ x0 := mul ?a ?b, x1 := mul ?a ?b' |- _ ]
+ => subst x0 x1
+ | [ x0 := mul ?a ?b, x1 := mul ?a' ?b |- _ ]
+ => subst x0 x1
+ end.
+
Ltac set_nonfraction_pieces_on T eq zero opp add sub mul inv div nonzero_tac cont :=
idtac;
let one_arg_recr :=
@@ -656,7 +682,8 @@ Ltac set_nonfraction_pieces_in_by H nonzero_tac :=
=> let T := type of H in
set_nonfraction_pieces_on
T eq zero opp add sub mul inv div nonzero_tac
- ltac:(fun T' => change T' in H)
+ ltac:(fun T' => change T' in H);
+ deduplicate_nonfraction_pieces mul
end.
Ltac set_nonfraction_pieces_by nonzero_tac :=
idtac;
@@ -666,31 +693,53 @@ Ltac set_nonfraction_pieces_by nonzero_tac :=
=> let T := get_goal in
set_nonfraction_pieces_on
T eq zero opp add sub mul inv div nonzero_tac
- ltac:(fun T' => change T')
+ ltac:(fun T' => change T');
+ deduplicate_nonfraction_pieces mul
end.
Ltac set_nonfraction_pieces_in H :=
set_nonfraction_pieces_in_by H ltac:(try (intro; field_nonzero_mul_split; try tauto)).
Ltac set_nonfraction_pieces :=
set_nonfraction_pieces_by ltac:(try (intro; field_nonzero_mul_split; tauto)).
Ltac conservative_common_denominator_in H :=
- set_nonfraction_pieces_in H;
- [ ..
- | common_denominator_in H;
- [ repeat split; try assumption..
- | ] ];
- repeat match goal with H := _ |- _ => subst H end.
+ idtac;
+ let fld := guess_field in
+ let div := lazymatch type of fld with
+ | @field ?T ?eq ?zero ?one ?opp ?add ?sub ?mul ?inv ?div
+ => div
+ end in
+ lazymatch type of H with
+ | appcontext[div]
+ => set_nonfraction_pieces_in H;
+ [ ..
+ | common_denominator_in H;
+ [ repeat split; try assumption..
+ | ] ];
+ repeat match goal with H := _ |- _ => subst H end
+ | ?T => fail 0 "no division in" H ":" T
+ end.
Ltac conservative_common_denominator :=
- set_nonfraction_pieces;
- [ ..
- | common_denominator;
- [ repeat split; try assumption..
- | ] ];
- repeat match goal with H := _ |- _ => subst H end.
+ idtac;
+ let fld := guess_field in
+ let div := lazymatch type of fld with
+ | @field ?T ?eq ?zero ?one ?opp ?add ?sub ?mul ?inv ?div
+ => div
+ end in
+ lazymatch goal with
+ | |- appcontext[div]
+ => set_nonfraction_pieces;
+ [ ..
+ | common_denominator;
+ [ repeat split; try assumption..
+ | ] ];
+ repeat match goal with H := _ |- _ => subst H end
+ | |- ?G
+ => fail 0 "no division in goal" G
+ end.
Ltac conservative_common_denominator_all :=
try conservative_common_denominator;
[ ..
- | repeat match goal with [H: _ |- _ _ _ ] => progress conservative_common_denominator_in H; [] end ].
+ | repeat match goal with [H: _ |- _ ] => progress conservative_common_denominator_in H; [] end ].
Inductive field_simplify_done {T} : T -> Type :=
Field_simplify_done : forall H, field_simplify_done H.
diff --git a/src/Tactics/Nsatz.v b/src/Tactics/Nsatz.v
index 84d472e54..04f35c200 100644
--- a/src/Tactics/Nsatz.v
+++ b/src/Tactics/Nsatz.v
@@ -85,7 +85,8 @@ Ltac nsatz_clear_duplicates_for_bug_4851 domain :=
Ltac nsatz_nonzero :=
try solve [apply Integral_domain.integral_domain_one_zero
|apply Integral_domain.integral_domain_minus_one_zero
- |trivial].
+ |trivial
+ |assumption].
Ltac nsatz_domain_sugar_power domain sugar power :=
let nparams := constr:(BinInt.Zneg BinPos.xH) in (* some symbols can be "parameters", treated as coefficients *)
diff --git a/src/Util/Tactics.v b/src/Util/Tactics.v
index e8876fee2..2324e1b34 100644
--- a/src/Util/Tactics.v
+++ b/src/Util/Tactics.v
@@ -111,3 +111,10 @@ Ltac destruct_trivial_step :=
| [ H : True |- _ ] => clear H || destruct H
end.
Ltac destruct_trivial := repeat destruct_trivial_step.
+
+Ltac clear_duplicates_step :=
+ match goal with
+ | [ H : ?T, H' : ?T |- _ ] => clear H'
+ | [ H := ?T, H' := ?T |- _ ] => clear H'
+ end.
+Ltac clear_duplicates := repeat clear_duplicates_step.