aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jason Gross <jgross@mit.edu>2016-10-26 15:12:34 -0400
committerGravatar Jason Gross <jgross@mit.edu>2016-10-26 15:12:34 -0400
commitc2a9824de5ccc1721d0f41a1d0f770806b67f631 (patch)
tree16faaaea15d4d9e72fbb5a70de84dc9a0c5372a1 /src
parenta4bd83ef618c680ce4b3da1db6e3d1906700ddf7 (diff)
Add tactics to implement better fraction removal
Diffstat (limited to 'src')
-rw-r--r--src/Algebra.v65
-rw-r--r--src/Util/Tactics.v8
2 files changed, 72 insertions, 1 deletions
diff --git a/src/Algebra.v b/src/Algebra.v
index 1f08c0464..78255f94e 100644
--- a/src/Algebra.v
+++ b/src/Algebra.v
@@ -1244,6 +1244,71 @@ Ltac field_simplify_eq_hyps :=
Ltac field_simplify_eq_all := field_simplify_eq_hyps; try field_simplify_eq.
+(** *** Tactics that remove division by rewriting *)
+Ltac rewrite_field_div_definition inv :=
+ let lem := constr:(field_div_definition (inv:=inv)) in
+ let div := lazymatch lem with field_div_definition (div:=?div) => div end in
+ repeat match goal with
+ | [ |- context[div _ _] ] => rewrite !lem
+ | [ H : context[div _ _] |- _ ] => rewrite !lem in H
+ end.
+Ltac generalize_inv inv :=
+ let lem := constr:(left_multiplicative_inverse (inv:=inv)) in
+ repeat match goal with
+ | [ |- context[inv ?x] ]
+ => pose proof (lem x); generalize dependent (inv x); intros
+ end.
+Ltac nsatz_strip_fractions_on inv :=
+ rewrite_field_div_definition inv; generalize_inv inv; specialize_by_assumption.
+
+Ltac nsatz_strip_fractions :=
+ match goal with
+ | [ |- ?eq ?x ?y ]
+ => let F := constr:(_ : Algebra.field (eq:=eq)) in
+ lazymatch type of F with
+ | Algebra.field (inv:=?inv) => nsatz_strip_fractions_on inv
+ end
+ | [ H : ?eq ?x ?y |- False ]
+ => let F := constr:(_ : Algebra.field (eq:=eq)) in
+ lazymatch type of F with
+ | Algebra.field (inv:=?inv) => nsatz_strip_fractions_on inv
+ end
+ end.
+
+Ltac nsatz_aggregate_inequalities :=
+ repeat match goal with
+ | _ => progress unfold not in *
+ | [ H : ((?R ?x ?zero) -> False)%type |- False ] => apply H; clear H
+ | [ |- ((?R ?x ?zero) -> False)%type ] => intro
+ | [ H : (?eq ?x ?zero -> False)%type |- ?eq ?y ?zero ]
+ => revert H; apply (proj2 (nonzero_hypothesis_to_goal x y))
+ end.
+
+Ltac nsatz_goal_to_canonical :=
+ try match goal with
+ | [ |- ?eq ?x ?y ]
+ => apply (move_leftR (eq:=eq)); rewrite <- ring_sub_definition;
+ lazymatch goal with
+ | [ |- eq _ y ] => fail 0 "should not subtract 0"
+ | _ => idtac
+ end
+ end.
+
+Ltac nsatz_specialize_by_cut :=
+ match goal with
+ | [ H : ((?eq ?x ?zero -> False) -> ?eq _ _)%type |- ?eq _ ?zero ]
+ => cut (not (eq x zero));
+ [ unfold not; intro; specialize_by_assumption; nsatz_specialize_by_cut
+ | clear H ]
+ | _ => idtac
+ end.
+
+Ltac nsatz_strip_fractions_and_aggregate_inequalities :=
+ nsatz_strip_fractions;
+ nsatz_goal_to_canonical;
+ nsatz_specialize_by_cut;
+ [ nsatz_aggregate_inequalities | .. ].
+
(** Clear duplicate hypotheses, and hypotheses of the form [R x x] for a reflexive relation [R], and similarly for symmetric relations *)
Ltac clear_algebraic_duplicates_step R :=
match goal with
diff --git a/src/Util/Tactics.v b/src/Util/Tactics.v
index d0c785fed..2f9f6c59f 100644
--- a/src/Util/Tactics.v
+++ b/src/Util/Tactics.v
@@ -263,7 +263,7 @@ Ltac specialize_by' tac :=
match goal with
| [ H : ?A -> ?B |- _ ] =>
match type of A with
- Prop =>
+ Prop =>
let H' := fresh in
assert (H' : A) by tac;
transparent_specialize_one H H';
@@ -279,6 +279,12 @@ Ltac specialize_by tac := repeat specialize_by' tac.
flaw. *)
Tactic Notation "specialize_by" tactic3(tac) := specialize_by tac.
+(** A marginally faster version of [specialize_by assumption] *)
+Ltac specialize_by_assumption :=
+ repeat match goal with
+ | [ H : ?T, H' : (?T -> ?U)%type |- _ ] => specialize (H' H)
+ end.
+
(** If [tac_in H] operates in [H] and leaves side-conditions before
the original goal, then
[side_conditions_before_to_side_conditions_after tac_in H] does