coq-将归纳假设应用于eqb_list_true_iff中的假设

时间:2019-08-15 09:45:42

标签: coq proof coq-tactic

我在业余时间正在研究软件基础书籍,这个问题对我来说尤其具有挑战性。这是卡住的地方:


Fixpoint eqb_list {A : Type} (eqb : A -> A -> bool)
                  (l1 l2 : list A) : bool :=
  match l1, l2 with
  | [], [] => true
  | [], _ => false
  | _, [] => false
  | (l1' :: l1s'), (l2' :: l2s') => (eqb l1' l2') && (eqb_list eqb l1s' l2s')
  end.

Lemma eqb_list_true_iff :
  forall A (eqb : A -> A -> bool),
    (forall a1 a2, eqb a1 a2 = true <-> a1 = a2) ->
    forall l1 l2, eqb_list eqb l1 l2 = true <-> l1 = l2.
Proof.
  intros. split.
  - intro. induction l1 as [|l1' l1s' IHl'].
  + destruct l2. { reflexivity. } { simpl in H0. discriminate H0. }
  + induction l2 as [|l2' l2s' Il2h']. { simpl in H0. discriminate. } { simpl in H0. }
Abort.

这是证明状态...

1 subgoal
A : Type
eqb : A -> A -> bool
H : forall a1 a2 : A, eqb a1 a2 = true <-> a1 = a2
l1' : A
l1s' : list A
x : A
l2 : list A
H0 : eqb l1' x && eqb_list eqb l1s' l2 = true
IHl' : eqb_list eqb l1s' (x :: l2) = true ->
       l1s' = x :: l2
______________________________________(1/1)
l1' :: l1s' = x :: l2

我可以轻松地隔离eqb l1' x并在下面进行一些重写,以使列表的头(l1'x)相等,而表尾(l1sl2)杀死了我。我的直觉说,通过以某种方式将IHl'应用于H0,我可以前进,但是我无法找到一种方法来普遍地归纳归纳假设,也无法找到一种方法来按摩H0使其类似于IHl'。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:3)

归纳假设太弱了。非正式地,您可以期望证明的一部分像这样:

  

我们想证明l1 :: l1s = x :: l2',因为足以证明:

     
      
  1. l1 = x(使用eqb参数的假设)和
  2.   
  3. l1s = l2'
  4.   

后一种说法应从归纳假设中得出。因此,归纳假设应该说一些关于比较l1sl2'的事情。但是,您当前目标中的IHl'是将l1sx :: l2'进行比较。

问题在于,第一个induction l1是在目标“ l1 = l2”上完成的:此时l2是固定的,因此在归纳情况下,归纳假设将将l1的尾部与l2进行比较,而不是与l2的尾部进行比较。

简而言之,目标过于具体,无法通过归纳直接证明。必须首先将其概括。 Software Foundations的“战术”一章(改变归纳假设)说明了如何解决此问题。

(我故意不放弃实际的解决方案,因为这是一个家庭作业问题,但随时可以要求进一步的澄清。)