coq-club AT inria.fr
Subject: The Coq mailing list
List archive
- From: Hugo Herbelin <Hugo.Herbelin AT inria.fr>
- To: Benjamin Pierce <bcpierce AT cis.upenn.edu>
- Cc: coq-club AT inria.fr
- Subject: Re: [Coq-Club] Curly braces in Coq notations
- Date: Mon, 23 Oct 2023 13:19:40 +0200
- Authentication-results: mail3-relais-sop.national.inria.fr; dkim=none (message not signed) header.i=none; spf=None smtp.mailfrom=herbelin AT yquem.paris.inria.fr; spf=None smtp.helo=postmaster AT yquem.paris.inria.fr
Hi,
This is also due to the special status of { } which is predefined at
level 0 with syntax "{ x }". In "(<{ { X > 0 } X := 0 { true } }>)",
the right-hand side of :=, a term at level 0, is parsed as "0 { true }",
that is as 0 applied to the notation "{ true }".
I'm afraid you'd have to renounce to the notation
Notation "f x .. y" := (.. (f x) .. y)
(in custom com at level 0, only parsing,
f constr at level 0, x constr at level 9,
y constr at level 9) : com_scope.
in custom entry com, or to replace it e.g. with a notation of the form
"f ( x , .. , y )", etc.
This special notation "{ x }" was there to implement the "historical"
notations "{ x } + { y }" for sumbool and "x + { y }" for sumor, and
their nesting as in "{ x } + { y } + { z }". We did not find a way
to do it without introducing a stand-alone "{ x }".
Hope it helps,
Hugo
On Sun, Oct 22, 2023 at 04:06:46PM -0400, Benjamin Pierce wrote:
> Many thanks, Gaëtan! Yes, this works.
>
> May I trouble you (and/or others) with one further question? When I scale
> this
> up to the full Imp language, it seems to get me almost everything I want,
> but I
> am still puzzled by why I can't omit the parentheses on the very last line
> below. I've tried tweaking various precedence levels, but have not found
> the
> right combination...
>
> - B
>
>
> From Coq Require Import Strings.String. Import String.
> From Coq Require Import Bool.Bool.
> From Coq Require Import Init.Nat.
> From Coq Require Import Arith.Arith.
> From Coq Require Import Arith.EqNat. Import Nat.
> From Coq Require Import Lia.
> From Coq Require Import Lists.List. Import ListNotations.
> From PLF Require Import Maps.
>
> Declare Custom Entry com.
> Declare Custom Entry com_aux.
> Declare Scope com_scope.
> Open Scope com_scope.
>
> Definition state := total_map nat.
>
> Inductive aexp : Type :=
> | ANum (n : nat)
> | AId (x : string)
> | APlus (a1 a2 : aexp)
> | AMinus (a1 a2 : aexp)
> | AMult (a1 a2 : aexp).
>
> Definition W : string := "W".
> Definition X : string := "X".
> Definition Y : string := "Y".
> Definition Z : string := "Z".
>
> Inductive bexp : Type :=
> | BTrue
> | BFalse
> | BEq (a1 a2 : aexp)
> | BNeq (a1 a2 : aexp)
> | BLe (a1 a2 : aexp)
> | BGt (a1 a2 : aexp)
> | BNot (b : bexp)
> | BAnd (b1 b2 : bexp).
>
> Coercion AId : string >-> aexp.
> Coercion ANum : nat >-> aexp.
>
> Notation "<{ e }>" := e (e custom com_aux) : com_scope.
> Notation "e" := e (in custom com_aux at level 0, e custom com) :
> com_scope.
>
> Notation "( x )" := x (in custom com, x at level 98) : com_scope.
> Notation "x" := x (in custom com at level 0, x constr at level 0) :
> com_scope.
> Notation "f x .. y" := (.. (f x) .. y)
> (in custom com at level 0, only parsing,
> f constr at level 0, x constr at level 9,
> y constr at level 9) : com_scope.
>
> Notation "x + y" := (APlus x y) (in custom com at level 50, left
> associativity).
> Notation "x - y" := (AMinus x y) (in custom com at level 50, left
> associativity).
> Notation "x * y" := (AMult x y) (in custom com at level 40, left
> associativity).
> Notation "'true'" := true (at level 1).
> Notation "'true'" := BTrue (in custom com at level 0).
> Notation "'false'" := false (at level 1).
> Notation "'false'" := BFalse (in custom com at level 0).
> Notation "x <= y" := (BLe x y) (in custom com at level 70, no
> associativity).
> Notation "x > y" := (BGt x y) (in custom com at level 70, no
> associativity).
> Notation "x = y" := (BEq x y) (in custom com at level 70, no
> associativity).
> Notation "x <> y" := (BNeq x y) (in custom com at level 70, no
> associativity).
> Notation "x && y" := (BAnd x y) (in custom com at level 80, left
> associativity).
> Notation "'~' b" := (BNot b) (in custom com at level 75, right
> associativity).
>
> Locate "=".
> Check <{ X + Y }>.
> Check <{ X + Y = 0 }>.
> Check <{ ~ (Y = X) }>.
> Check <{ X + Y }>.
> Check <{ ~ (X + Y = Y) && Z = W }>.
>
> Inductive com : Type :=
> | CSkip
> | CAsgn (x : string) (a : aexp)
> | CSeq (c1 c2 : com)
> | CIf (b : bexp) (c1 c2 : com)
> | CWhile (b : bexp) (c : com).
>
> Notation "'skip'" :=
> CSkip (in custom com at level 0) : com_scope.
> Notation "x := y" :=
> (CAsgn x y)
> (in custom com at level 0, x constr at level 0,
> y at level 85, no associativity) : com_scope.
> Notation "x ; y" :=
> (CSeq x y)
> (in custom com at level 90,
> right associativity) : com_scope.
> Notation "'if' x 'then' y 'else' z 'end'" :=
> (CIf x y z)
> (in custom com at level 89, x at level 98,
> y at level 98, z at level 98) : com_scope.
> Notation "'while' x 'do' y 'end'" :=
> (CWhile x y)
> (in custom com at level 89, x at level 98,
> y at level 98) : com_scope.
>
> Check <{ skip }>.
> Check <{ (skip ; skip) ; skip }>.
> Check <{ 1 + 2 }>.
> Check <{ 2 = 1 }>.
> Check <{ Z := X }>.
> Check <{ Z := X + 3 }>.
> Definition func (c : com) : com := <{ c ; skip }>.
> Check <{ skip; func <{ skip }> }>.
> Definition func2 (c1 c2 : com) : com := <{ c1 ; c2 }>.
> Check <{ skip ; func2 <{skip}> <{skip}> }>.
> Check <{ true && ~(false && true) }>.
> Check <{ if true then skip else skip end }>.
> Check <{ if true && true then skip; skip else skip; X:=X+1 end }>.
> Check <{ while Z <> 0 do Y := Y * Z; Z := Z - 1 end }>.
>
> Fixpoint aeval (st : state) (* <--- NEW *)
> (a : aexp) : nat :=
> match a with
> | ANum n => n
> | AId x => st x (* <--- NEW *)
> | <{a1 + a2}> => (aeval st a1) + (aeval st a2)
> | <{a1 - a2}> => (aeval st a1) - (aeval st a2)
> | <{a1 * a2}> => (aeval st a1) * (aeval st a2)
> end.
>
> Fixpoint beval (st : state) (* <--- NEW *)
> (b : bexp) : bool :=
> match b with
> | <{true}> => true
> | <{false}> => false
> | <{a1 = a2}> => (aeval st a1) =? (aeval st a2)
> | <{a1 <> a2}> => negb ((aeval st a1) =? (aeval st a2))
> | <{a1 <= a2}> => (aeval st a1) <=? (aeval st a2)
> | <{a1 > a2}> => negb ((aeval st a1) <=? (aeval st a2))
> | <{~ b1}> => negb (beval st b1)
> | <{b1 && b2}> => andb (beval st b1) (beval st b2)
> end.
>
> Definition Assertion := state -> Prop.
>
> Definition Assert_of_bexp (b : bexp) : Assertion := fun st => beval st
> b =
> true.
>
> Notation "{ P } e { Q }" :=
> ((Assert_of_bexp P), e, (Assert_of_bexp Q))
> (in custom com_aux,
> e custom com,
> P custom com,
> Q custom com) : com_scope.
>
> Check (<{ X > 0 }>).
> Check (<{ X := 0 }>).
> Check (<{ { X > 0 } (X := 0) { true } }>).
> Check (<{ { X > 0 } X := 0 { true } }>).
>
>
>
>
- [Coq-Club] Curly braces in Coq notations, Benjamin Pierce, 10/22/2023
- Re: [Coq-Club] Curly braces in Coq notations, Gaëtan Gilbert, 10/22/2023
- Re: [Coq-Club] Curly braces in Coq notations, Benjamin Pierce, 10/22/2023
- Re: [Coq-Club] Curly braces in Coq notations, Hugo Herbelin, 10/23/2023
- Re: [Coq-Club] Curly braces in Coq notations, Hugo Herbelin, 10/23/2023
- Re: [Coq-Club] Curly braces in Coq notations, Benjamin Pierce, 10/23/2023
- Re: [Coq-Club] Curly braces in Coq notations, Hugo Herbelin, 10/23/2023
- Re: [Coq-Club] Curly braces in Coq notations, Hugo Herbelin, 10/23/2023
- Re: [Coq-Club] Curly braces in Coq notations, Benjamin Pierce, 10/22/2023
- Re: [Coq-Club] Curly braces in Coq notations, Gaëtan Gilbert, 10/22/2023
Archive powered by MHonArc 2.6.19+.