我试图证明在一个词上对空替换的应用等于给定的术语。 这是代码:
anchorLeft
我试图证明这个功能的一些属性。
Require Import Coq.Strings.String.
Require Import Coq.Lists.List.
Require Import Coq.Arith.EqNat.
Require Import Recdef.
Require Import Omega.
Import ListNotations.
Set Implicit Arguments.
Inductive Term : Type :=
| Var : nat -> Term
| Fun : string -> list Term -> Term.
Definition Subst : Type := list (nat*Term).
Definition maybe{X Y: Type} (x : X) (f : Y -> X) (o : option Y): X :=
match o with
|None => x
|Some a => f a
end.
Fixpoint lookup {A B : Type} (eqA : A -> A -> bool) (kvs : list (A * B)) (k : A) : option B :=
match kvs with
|[] => None
|(x,y) :: xs => if eqA k x then Some y else lookup eqA xs k
end.
我反思后陷入困境。我希望在一个术语中对列表构建进行归纳,但如果我这样做,我将陷入循环中。 我将不胜感激任何帮助。
答案 0 :(得分:3)
这是初学者的典型陷阱。问题是你的Term
定义在另一个归纳类型中有一个递归的出现 - 在这种情况下,list
。不幸的是,Coq没有为这种类型产生有用的归纳原理;你必须自己编程。 Adam Chlipala的CDPT has a chapter on inductive types描述了这个问题。只需寻找“嵌套归纳类型”。
答案 1 :(得分:3)
问题是Term
类型的自动生成的归纳原理太弱了,因为它内部有另一个归纳类型list
(具体来说,list
适用于正在建造的类型)。 Adam Chlipala的CPDT很好地解释了发生了什么,以及如何在inductive types chapter中为这些类型手动建立更好的归纳原则的例子。我已使用内置nat_tree_ind'
而不是自定义定义,为您的Term
归纳调整了他的示例Forall
原则。有了它,你的定理就很容易证明:
Section Term_ind'.
Variable P : Term -> Prop.
Hypothesis Var_case : forall (n:nat), P (Var n).
Hypothesis Fun_case : forall (s : string) (ls : list Term),
Forall P ls -> P (Fun s ls).
Fixpoint Term_ind' (tr : Term) : P tr :=
match tr with
| Var n => Var_case n
| Fun s ls =>
Fun_case s
((fix list_Term_ind (ls : list Term) : Forall P ls :=
match ls with
| [] => Forall_nil _
| tr'::rest => Forall_cons tr' (Term_ind' tr') (list_Term_ind rest)
end) ls)
end.
End Term_ind'.
Lemma empty_apply_on_term:
forall t, apply [] t = t.
Proof.
intros.
induction t using Term_ind'; simpl; auto.
f_equal.
induction H; simpl; auto.
congruence.
Qed.