From f9ef87453212f021b8ae352b2eaa45e89f52615f Mon Sep 17 00:00:00 2001 From: Sergei Bozhko <sbozhko@mpi-sws.org> Date: Mon, 19 Jul 2021 17:10:39 +0200 Subject: [PATCH] Add setoid rewrite --- scripts/wordlist.pws | 5 +++- util/all.v | 1 + util/setoid.v | 69 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 util/setoid.v diff --git a/scripts/wordlist.pws b/scripts/wordlist.pws index 355d82b53..48cb9fea3 100644 --- a/scripts/wordlist.pws +++ b/scripts/wordlist.pws @@ -62,4 +62,7 @@ superadditive subadditivity subadditive ad -hoc \ No newline at end of file +hoc +mailinglist +Gonthier +setoid \ No newline at end of file diff --git a/util/all.v b/util/all.v index c80df7935..cdc1a9d95 100644 --- a/util/all.v +++ b/util/all.v @@ -16,3 +16,4 @@ Require Export prosa.util.minmax. Require Export prosa.util.supremum. Require Export prosa.util.nondecreasing. Require Export prosa.util.rewrite_facilities. +Require Export prosa.util.setoid. diff --git a/util/setoid.v b/util/setoid.v new file mode 100644 index 000000000..f6bd2d8e6 --- /dev/null +++ b/util/setoid.v @@ -0,0 +1,69 @@ +(** Setoid Rewriting with boolean inequalities of ssreflect. Solution + suggested by Georges Gonthier (ssreflect mailinglist @ 18.12.2016) *) + +From Coq Require Import Basics Setoid Morphisms. +From mathcomp Require Import ssreflect ssrfun ssrbool eqtype ssrnat. + +(** This construction allows us to "rewrite" inequalities with ≤. *) + +Inductive leb a b := Leb of (a ==> b). + +Lemma leb_eq a b : leb a b <-> (a -> b). +Proof. move: a b => [|] [|]; firstorder. Qed. + +Instance : PreOrder leb. +Proof. split => [[|]|[|][|][|][?][?]]; try exact: Leb. Qed. + +Instance : Proper (leb ==> leb ==> leb) andb. +Proof. move => [|] [|] [A] c d [B]; exact: Leb. Qed. + +Instance : Proper (leb ==> leb ==> leb) orb. +Proof. move => [|] [|] [A] [|] d [B]; exact: Leb. Qed. + +Instance : Proper (leb ==> impl) is_true. +Proof. move => a b []. exact: implyP. Qed. + +Instance : Proper (le --> le ++> leb) leq. +Proof. move => n m /leP ? n' m' /leP ?. apply/leb_eq => ?. eauto using leq_trans. Qed. + +Instance : Proper (le ==> le ==> le) addn. +Proof. move => n m /leP ? n' m' /leP ?. apply/leP. exact: leq_add. Qed. + +Instance : Proper (le ++> le --> le) subn. +Proof. move => n m /leP ? n' m' /leP ?. apply/leP. exact: leq_sub. Qed. + +Instance : Proper (le ==> le) S. +Proof. move => n m /leP ?. apply/leP. by rewrite ltnS. Qed. + +Instance : RewriteRelation le. +Defined. + +Definition leqRW {m n} : m <= n -> le m n := leP. + +(** To see the benefits, consider the following example. *) +(* +[Goal ] +[ forall a b c d x y, ] +[ x <= y -> ] +[ a + (b + (x + c)) + d <= a + (b + (y + c)) + d. ] +[Proof. ] +[ move => a b c d x y LE. ] +[ (* This could be an unpleasant proof, but we can just [rewrite LE] *) ] +[ by rewrite (leqRW LE). (* magic here *) ] +[Qed. ] +*) + +(** Another benefit of [leqRW] is that it allows + to avoid unnecessary [eapply leq_trans]. *) +(* +[Goal ] +[ forall a b x y z, ] +[ a <= x -> ] +[ b <= y -> ] +[ x + y <= z -> ] +[ a + b <= z. ] +[Proof. ] +[ move => a b x y z LE1 LE2 LE3. ] +[ rewrite -(leqRW LE3) leq_add //. ] +[Qed. ] +*) -- GitLab