Coq,元编程,生成新变量以创建Prop

时间:2017-11-26 12:00:10

标签: metaprogramming coq

我有自己的类型Mytype,它定义了一种公式。我想将此公式转换为Coq命题Prop。为此,我觉得我需要某种元编程,让我写forall <variable 15>, <variable 15> /\ <variable (15+1)>

这是我要翻译的MWE:

Inductive Myprop : Type :=
| MTrue
| MFalse
| MVar (_ : nat)
| MAnd (_ : Myprop) (_ : Myprop)
| MOr (_ : Myprop) (_ : Myprop)
| MForall (_ : nat) (_ : Myprop)
.

(* Exemple *)
Eval simpl in MForall 42 (MForall 42 (MOr (MVar 42) (MVar 50))).

Fixpoint translate (myprop : Myprop) : Prop :=
  match myprop with
  | MTrue => True
  | MFalse => False
  | MVar n => (* ???? Variable n ??? *)
  | MAnd a b => (translate a) /\ (translate b)
  | MOr  a b => (translate a) \/ (translate b)
  | MForall n a => forall (* ???? Variable n ??? *), (translate a)
  end.

谢谢!

1 个答案:

答案 0 :(得分:2)

正如加利斯建议的那样,您可以使用上下文查找功能扩充translate函数:

Fixpoint translate (lookup : nat -> Prop) (myprop : Myprop) : Prop :=
  match myprop with
  | MTrue => True
  | MFalse => False
  | MVar n => lookup n
  | MAnd a b => (translate lookup a) /\ (translate lookup b)
  | MOr  a b => (translate lookup a) \/ (translate lookup b)
  | MForall n a => forall p : Prop,
      translate (fun n' => if Nat.eqb n' n then p else lookup n') a
  end.

Eval compute in translate _ (MForall 42 (MForall 42 (MOr (MVar 42) (MVar 50)))).
(* Prop -> forall p0 : Prop, p0 \/ ?lookup 50 *)

另一种方法是使用HOAS(高阶抽象语法),让你的绑定成为Gallina绑定:

Inductive Myprop : Type :=
| MTrue
| MFalse
| MVar (_ : Prop)
| MAnd (_ : Myprop) (_ : Myprop)
| MOr (_ : Myprop) (_ : Myprop)
| MForall (_ : Prop -> Myprop)
.

(* Exemple *)
Eval simpl in MForall (fun p42 => MForall (fun p42 => MOr (MVar p42) (MVar ?[p50]))).
(* ?[p50] denotes a fresh evar named "p50" *)

Fixpoint translate (myprop : Myprop) : Prop :=
  match myprop with
  | MTrue => True
  | MFalse => False
  | MVar P => P
  | MAnd a b => (translate a) /\ (translate b)
  | MOr  a b => (translate a) \/ (translate b)
  | MForall P => forall p : Prop, translate (P p)
  end.

Eval simpl in translate (MForall (fun p42 => MForall (fun p42 => MOr (MVar p42) (MVar ?[p50])))).
(* forall p p0 : Prop, p0 \/ ?p50@{p43:=p; p42:=p0} *)