1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

RocqのInductiveで相互帰納型を作ったときの帰納法

1
Posted at

背景

DLSなど設計していると相互帰納型がでてくることがよくあります。
例えば次のような構造の構文の言語を設計しているとします。

<statemnt> ::= 
  | "while" <expr> "{" <statement>* "}"
  | "return" <expr> ";"
  
<expr> ::=
  | <constant>
  | <variable>
  | <ident> "(" <expr> ")"  (* function application *)
  | "{" <statement>* "}"

Rocqで書くと次のような書き方になると思います。

Inductive statment :=
| While : expr -> statement list -> statement
| Return : expr -> statement
with expr :=
| Constant : nat -> expr
| Var : var -> expr
| FunCall : string -> expr -> expr
| Block : statement list -> expr.

問題点

RocqではInductive型に対して XXX_ind という名前で帰納法の原理を自動生成してくれますが、相互帰納型の場合これがうまく生成されないんです。

我々の例の場合 statement_ind という項が自動生成されるんですが、使ってみるとわかるように使い物になりません。 expr_ind も同様。

statement_ind :
   forall [P : statement -> Prop],
   (forall (e : expr) (l : seq statement), P (While e l)) ->
   (forall e : expr, P (Return e)) -> forall s : statement, P s

解決方

ではどうすればよいか。

Scheme statement_mut := Induction for statement Sort Prop
with expr_mut := Induction for expr Sort Prop.

↑これによって以下のような帰納法の原理が生成されます :thumbsup:

statement_mut :
  forall [P : statement -> Prop] [P0 : expr -> Prop],
  (forall e : expr, P0 e -> forall l : seq statement, P (While e l)) ->
  (forall e : expr, P0 e -> P (Return e)) ->
  (forall n : nat, P0 (Constant n)) ->
  (forall v : var, P0 (Var v)) ->
  (forall (s : string) (e : expr), P0 e -> P0 (FunCall s e)) ->
  (forall l : seq statement, P0 (Block l)) -> forall s : statement, P s

参考文献

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?