Skip to Content.
Sympa Menu

coq-club - Re: [Coq-Club] Curly braces in Coq notations

coq-club AT inria.fr

Subject: The Coq mailing list

List archive

Re: [Coq-Club] Curly braces in Coq notations


Chronological Thread 
  • From: Benjamin Pierce <bcpierce AT cis.upenn.edu>
  • To: coq-club AT inria.fr
  • Subject: Re: [Coq-Club] Curly braces in Coq notations
  • Date: Sun, 22 Oct 2023 16:06:46 -0400
  • Authentication-results: mail3-smtp-sop.national.inria.fr; spf=None smtp.pra=bcpierce AT cis.upenn.edu; spf=Pass smtp.mailfrom=bcpierce AT seas.upenn.edu; spf=None smtp.helo=postmaster AT mail-ua1-f50.google.com
  • Ironport-data: A9a23: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
  • Ironport-hdrordr: A9a23:m9e/eKD842pCxuPlHemV55DYdb4zR+YMi2TDtnoBMCC9F/bzqy nApoV/6faZskdyZJhko6HiBEDiexLhHPxOkO0s1N6ZNWGMhILrFuFfBODZslrd8kPFh4hgPG RbH5SWyuecMbG3t6nHCcCDfeod/A==
  • Ironport-phdr: A9a23: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
  • Ironport-sdr: 653580fd_3q7WRrpsmZxKuhKWsL6tYmGs4JofsKQKLJZTKJZopBZsvJh 1z75+eSzpq0S5zBtKopfsIUCrdeOmds9gnbTbwA==

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 } }>).





Archive powered by MHonArc 2.6.19+.

Top of Page