产品类型的相互递归函数

时间:2019-12-04 08:22:20

标签: coq mutual-recursion

(初级Coq问题)

Defining recursive function over product type相关,我正在尝试为产品类型定义递归函数。区别在于这里有一个相互递归的定义。我一直遇到这个错误:

  

printObjItem的递归定义格式不正确。

     

对printJson的递归调用的主参数等于“ val”,而不是   “ item”的子项。

从概念上讲,似乎应该进行递归,因为valitem的子项,是items的子项,是x的子项。我知道Coq正在为第一个断言而苦苦挣扎,但我不确定如何解决。没有明确的充分依据的证据,有没有一种直接的方法?

Require Import List.
Require Import String.
Import ListNotations.

Inductive Json :=
  | Atom : Json
  | String : string -> Json
  | Array : nat -> list Json -> Json
  | Object : list (string * Json) -> Json.

Fixpoint printJson (x : Json) :=
  match x with
  | Atom => "atom"
  | String n => "'" ++ n ++ "'"
  | Array _ els => "[" ++ (String.concat ", " (map printJson els)) ++ "]"
  | Object items => "{" ++ (String.concat ", " (map printObjItem items)) ++ "}"
  end%string
with printObjItem (item : string * Json) :=
       let (key, val) := item in key ++ ": " ++ (printJson val).

1 个答案:

答案 0 :(得分:2)

一种解决方案是使printObjItem为本地定义:

Fixpoint printJson (x : Json) :=
  let printObjItem (item : string * Json) :=
    (let (key, val) := item in key ++ ": " ++ (printJson val))%string
  in
  match x with
  | Atom => "atom"
  | String n => "'" ++ n ++ "'"
  | Array _ els => "[" ++ (String.concat ", " (map printJson els)) ++ "]"
  | Object items => "{" ++ (String.concat ", " (map printObjItem items)) ++ "}"
  end%string.