Coq 在定义BNF样式定义之前使用标识符

Coq 在定义BNF样式定义之前使用标识符,coq,Coq,在定义BNF语法时,通常在定义它们之前使用它们,以便语法读作“向前” 如何在coq中做到这一点,并且仍然能够分步通过缓冲区?在coq中,缓冲区的概念不是预定义的,因此很难理解您的意思。Coq仍然有两个方面给人一种可能的前瞻感,在定义BNF语法时可以使用这两个方面 递归函数定义可以同时引入多个递归函数 类型定义可以同时引入多个归纳类型 在这两种情况下,定义的第一个对象可以在定义前引用第二个对象 这里有两个例子,第一个是关于递归函数的 Fixpoint even (n : nat) : bool

在定义BNF语法时,通常在定义它们之前使用它们,以便语法读作“向前”

如何在coq中做到这一点,并且仍然能够分步通过缓冲区?

在coq中,缓冲区的概念不是预定义的,因此很难理解您的意思。Coq仍然有两个方面给人一种可能的前瞻感,在定义BNF语法时可以使用这两个方面

  • 递归函数定义可以同时引入多个递归函数
  • 类型定义可以同时引入多个归纳类型
在这两种情况下,定义的第一个对象可以在定义前引用第二个对象

这里有两个例子,第一个是关于递归函数的

Fixpoint even (n : nat) : bool :=
   match n with
     0 => true
   | S p => negb( odd p)
   end
with odd (n : nat) : bool :=
  match n with
    0 => false
  | S p => negb (even p)
  end.
在本例中可以看到,函数
偶数
在定义之前引用了函数
奇数

现在是第二个例子。我试图坚持你对BNF的主要比喻。语法描述可以作为归纳谓词给出。下面是一个小示例,其中包含仅涉及加法、乘法和自然数的算术表达式语法

Require Import String Ascii Arith.

Definition digit (c : ascii) : bool :=
  (nat_of_ascii "0" <=? nat_of_ascii c) &&
  (nat_of_ascii c <=? nat_of_ascii "9").

Fixpoint number (s : string) : bool :=
  match s with
  | String c EmptyString => digit c
  | String c tl => digit c && number tl
  | EmptyString => false
  end.

Inductive Exp1 : string -> Prop :=
  plus : forall x y, Exp2 x -> Exp1 y -> Exp1 (x ++ "+" ++ y)
| inj2 : forall x, Exp2 x -> Exp1 x
with
  Exp2 : string -> Prop :=
  times : forall x y, Exp3 x -> Exp2 y -> Exp2 (x ++ "*" ++ y)
| inj3 : forall x, Exp3 x -> Exp2 x
with
  Exp3 : string -> Prop :=
|  num : forall x, number x = true -> Exp3 x
|  inj1 : forall x, Exp1 x -> Exp3 ("(" ++ x ++ ")").
这并不描述解析器。这将是另一个练习


你的问题如此简洁,我甚至不知道这是否是一个答案。

没错,是的。我没有意识到ML“with”样式可以用于归纳定义。。。这使得文档的情况有点混乱(因为大多数语法都需要在一个定义中编写),但这给了我所需要的。如果您想分几个步骤编写语法,您仍然可以利用规范语言的高阶功能。
Lemma example : Exp1 "3+2*(5*4)".
Proof.
apply (plus "3" "2*(5*4)").
  apply inj3.
  apply num; reflexivity.
apply inj2.
apply (times "2" "(5*4)").
  apply num; reflexivity.
apply inj3, (inj1 "5*4"), inj2, (times "5" "4").
  apply num; reflexivity.
apply inj3, num; reflexivity.
Qed.