【问题标题】:Induction in Coq on a tree structureCoq 在树结构上的归纳
【发布时间】:2026-02-12 11:40:01
【问题描述】:

这是一个非常基本的问题,我很抱歉,但我一直在尝试使用 Coq 来证明以下定理,但似乎无法弄清楚如何去做。

(* Binary tree definition. *)
Inductive btree : Type := 
  | EmptyTree
  | Node : btree -> btree -> btree.
(* Checks if two trees are equal. *)

Fixpoint isEqual (tree1 : btree) (tree2 : btree) : bool :=
  match tree1, tree2 with
    | EmptyTree, EmptyTree => true
    | EmptyTree, _ => false
    | _, EmptyTree => false
    | Node n11 n12, Node n21 n22 => (andb (isEqual n11 n21) (isEqual n12 n22))
end.

Lemma isEqual_implies_equal : forall tree1 tree2 : btree, 
(isEqual tree1 tree2) = true -> tree1 = tree2.

我一直在尝试做的是在 tree1 上应用归纳,然后是 tree2,但这并不能正常工作。看来我需要同时对两者应用归纳,但不知道如何。

【问题讨论】:

    标签: coq


    【解决方案1】:

    我可以用简单的归纳法证明这一点

    Require Import Bool. (* Sorry! Forgot to add that the first time *)
    
    Lemma isEqual_implies_equal : forall tree1 tree2 : btree, 
    (isEqual tree1 tree2) = true -> tree1 = tree2.
      induction tree1, tree2; intuition eauto.
      inversion H.
      inversion H.
      apply andb_true_iff in H.
      intuition eauto; fold isEqual in *.
      apply IHtree1_1 in H0.
      apply IHtree1_2 in H1.
      congruence.
    Qed.
    
    (* An automated version *)
    Lemma isEqual_implies_equal' : forall tree1 tree2 : btree, 
    (isEqual tree1 tree2) = true -> tree1 = tree2.
      induction tree1, tree2; intuition; simpl in *;
      repeat match goal with
                | [ H : false = true |- _ ]   => inversion H
                | [ H : (_ && _) = true |- _] => apply andb_true_iff in H; intuition
                | [ IH : context[ _ = _ -> _], 
                    H : _ = _ |- _]           => apply IH in H
             end; congruence.
      Qed.
    

    通过在intros 之前应用induction,我们的归纳假设在tree2 上具有多态性,这允许我们在最终情况下使用它。

    【讨论】:

    • 酷,谢谢,这基本上对我有用,但我必须做一些调整。首先是我没有定义 andb_true_iff ——我猜这是在某个库中,但我得到了要点并为它制定了自己的定理(见上文)。我想我可以问的最重要的问题是:为什么我可以使用 IHtree1_1 和 IHtree1_2 当它们都引用 tree2 而不是 tree2_1 或 (Node tree2_1 tree2_2) 或类似的东西时?我觉得答案将包含在您的短语“tree2 上的多态性,它允许我们在最终情况下使用它”中。那么tree2没有定义吗?
    • 酷。需要导入布尔值。成功了。我对 Coq 非常非常陌生(你可能已经了解了),所以像这样应该很明显的事情还没有。
    • @quadelirus 不,那是我的错 :) 我只是从 emacs 复制和粘贴,却没有意识到我的导入位于顶部