我正在尝试在Coq中定义一个名为interval的函数,给定两个自然数来计算这两者之间所有自然数的列表。但是我的定义不是原始 - 递归的。这是我的代码:
Require Coq.Program.Tactics.
Require Coq.Program.Wf.
Inductive bool : Type :=
| true : bool
| false : bool.
Fixpoint leq_nat (m:nat) (n:nat) : bool :=
match m with
| 0 => true
| S x => match n with
| 0 => false
| S y => leq_nat x y
end
end.
Notation "m <= n" := (leq_nat m n).
Notation "x :: l" := (cons x l) (at level 60, right associativity).
Program Fixpoint intervalo (m:nat) (n:nat) {measure ((S n) - m)}: list nat :=
match m <= n with
| false => nil
| true => m :: (intervalo (S m) n)
end.
Next Obligation.
正如您所看到的,我在间隔的长度上使用了有根据的递归。我将度量定义为该值,即S n - m。
我希望被要求证明forall m, n, true = m <= n -> S n - S m < S n - m
然而,我得到的证明义务看起来并不像这样,而且相当混乱。我被要求证明:
m : nat
n : nat
intervalo : forall m0 n0 : nat,
match m0 with
| 0 => S n0
| S l => n0 - l
end < match m with
| 0 => S n
| S l => n - l
end -> list nat
Heq_anonymous : true = (m <= n)
============================
n - m < match m with
| 0 => S n
| S l => n - l
end
那:
============================
well_founded
(Wf.MR lt
(fun recarg : {_ : nat & nat} =>
match projT1 recarg with
| 0 => S (projT2 recarg)
| S l => projT2 recarg - l
end))
有人可以解释一下,为什么Coq要求我证明这一点,而不仅仅是forall m, n, true = m <= n -> S n - S m < S n - m
。另外,我怎样才能完成这个证明?或者我怎样才能让它看起来更像是我期待Coq要求我证明的?
谢谢。
答案 0 :(得分:1)
这里让您感到困惑的是,S n - m
一词部分展开,您还有另外一个假设。如果输入:
clear intervalo.
change (match m with
| 0 => S n
| S l => n - l
end) with (S n - m).
change (n - m) with (S n - S m).
然后你会发现你被要求证明的第一个目标确实是forall m, n, true = m <= n -> S n - S m < S n - m
的直接后果。
第二个是简单地说明你的衡量标准是有充分根据的(再次出现S n - m
的某种程度的展开)。我可能有一个不同版本的Coq(版本8.5beta2),因为在我的情况下,这个东西会自动释放。