Coq 模块系统的定义扩展问题

Issue on definition expansion from Coq module system

我已经在 Coq 中定义了几个模块来从 Bit 类型递归地构建 Byte 类型,作为一对三。但是我遇到了为字节类型定义 Numeral Notation 的问题。

代码如下:

Require Import ZArith.

(* bit sequence abstracted interface *)
Module Type Numeric.
    Parameter T: Set.
    Parameter MAX: T.                          (* sequence of 1...1 = 2^n - 1 *)
    Parameter to: T -> Z.                      (* conversion to Z *)
    Parameter of: Z -> option T.               (* conversion from Z *)
End Numeric.

(* a single bit *)
Module Bit.
    Inductive bit: Set := bit0 | bit1.
    Definition T: Set := bit.
    Definition MAX: T := bit1.
    Definition to (i: T): Z :=
        match i with
        | bit0 => 0%Z
        | bit1 => 1%Z
        end.
    Definition of (n: Z): option T :=
        match n with
        | Z0 => Some bit0
        | Zpos xH => Some bit1
        | _ => None
        end.
End Bit.

(* concatenation of two bit sequences *)
Module ConcatNumeric (m1 m2: Numeric).
    Definition T: Set := m1.T * m2.T.
    Definition MAX: T := (m1.MAX, m2.MAX).
    Definition to (x: T): Z :=
        let (x1, x2) := x in
        let i1 := m1.to x1 in
        let i2 := m2.to x2 in
        let base := (m2.to m2.MAX + 1)%Z in
        (i1 * base + i2)%Z.
    Definition of (i: Z): option T :=
        let base := (m2.to m2.MAX + 1)%Z in
        let i2 := (i mod base)%Z in
        let i1 := (i / base)%Z in
        match m1.of i1, m2.of i2 with
        | Some z1, Some z2 => Some (z1, z2)
        | _, _ => None
        end.
End ConcatNumeric.

(* hierarchy defining a byte from bits *)
Module Crumb: Numeric := ConcatNumeric Bit Bit.
Module Nibble: Numeric := ConcatNumeric Crumb Crumb.
Module Byte: Numeric := ConcatNumeric Nibble Nibble.

(* boxing Byte.T in an inductive type to make Numeral Notation happy *)
Inductive u8: Set := u8_box (x: Byte.T).
Definition u8_unbox := fun x => match x with u8_box x => x end.
Definition u8_of := fun i => option_map u8_box (Byte.of i).
Definition u8_to := fun x => Byte.to (u8_unbox x).

(* defines the scope and the Numeral Notation *)
Declare Scope u8_scope.
Delimit Scope u8_scope with u8.
Numeral Notation u8 u8_of u8_to: u8_scope.

(* testing the code *)    
Open Scope u8_scope.
Definition x: u8 := 1.     (* error here! *)

我收到此错误:

Error: Unexpected non-option term
match Byte.of 1 with
| Some a => Some (u8_box a)
| None => None
end while parsing a numeral notation.

这似乎不是 Numeral Notation 特有的,而是与 Byte.of 无法扩展这一事实相关的更普遍的问题。有人可以阐明正在发生的事情吗?如果有办法解决这个问题,这似乎是一个限制?

Coq 版本 8.11.2

当你写 Module Byte: Numeric := Foo 时,你告诉 Coq 删除 Foo 中的所有定义并只保留 Numeric 的签名。这会导致 Byte.of 丢失其 body。

在您的情况下,您不想将 Byte 的内容限制为 Numeric,而只是为了证明它与 Numeric 兼容。您可以使用 Module Byte <: Numeric := Foo.

顺便说一句,您可以将其移至 ConcatNumeric:

,而不是将此文档放在 Byte
Module ConcatNumeric (m1 m2: Numeric) <: Numeric.
  ...
End ConcatNumeric.
Module Byte := ConcatNumeric Nibble Nibble.