aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Util/LockedLet.v9
-rw-r--r--src/Util/Notations.v2
2 files changed, 11 insertions, 0 deletions
diff --git a/src/Util/LockedLet.v b/src/Util/LockedLet.v
new file mode 100644
index 000000000..088e914fb
--- /dev/null
+++ b/src/Util/LockedLet.v
@@ -0,0 +1,9 @@
+(** * A version of [let] that doesn't disappear under βδζ unless you also have ι and remove opacity *)
+Require Import Crypto.Util.Notations.
+
+Definition locked_let {A} (x : A) : bool * A := (true, x).
+Definition unlock_let {A} (x : A) : locked_let x = (true, x) := eq_refl.
+Global Opaque locked_let.
+Global Arguments locked_let : simpl never.
+
+Notation "'llet' x := A 'in' b" := (let '(_, x) := locked_let A in b).
diff --git a/src/Util/Notations.v b/src/Util/Notations.v
index 22ddf854c..99761c63b 100644
--- a/src/Util/Notations.v
+++ b/src/Util/Notations.v
@@ -63,6 +63,8 @@ Reserved Notation "'plet' x := y 'in' z"
(at level 200, z at level 200, format "'plet' x := y 'in' '//' z").
Reserved Notation "'slet' x := A 'in' b"
(at level 200, b at level 200, format "'slet' x := A 'in' '//' b").
+Reserved Notation "'llet' x := A 'in' b"
+ (at level 200, b at level 200, format "'llet' x := A 'in' '//' b").
(* Note that making [Let] a keyword breaks the vernacular [Let] in Coq 8.4 *)
Reserved Notation "'dlet' x := y 'in' f"
(at level 200, f at level 200, format "'dlet' x := y 'in' '//' f").