Coq 如何证明转换参数的关系的可判定性?

Coq 如何证明转换参数的关系的可判定性?,coq,proof,deterministic,formal-verification,partial-ordering,Coq,Proof,Deterministic,Formal Verification,Partial Ordering,我曾定义过一种归纳数据类型t,并在其上定义了一个偏序le(c.f.le\u refl,le\u trans,以及le\u antisym)。在le_C的情况下,顺序具有这种特殊性,即在归纳假设中参数的顺序被交换 正因为如此,我没有成功地证明这种排序关系是确定性的(c.f.le_dec)。有问题的子目标如下 1 subgoal t1 : t IHt1 : forall t2 : t, {le t1 t2} + {~ le t1 t2} t2 : t ________________________

我曾定义过一种归纳数据类型
t
,并在其上定义了一个偏序
le
(c.f.
le\u refl
le\u trans
,以及
le\u antisym
)。在
le_C
的情况下,顺序具有这种特殊性,即在归纳假设中参数的顺序被交换

正因为如此,我没有成功地证明这种排序关系是确定性的(c.f.
le_dec
)。有问题的子目标如下

1 subgoal
t1 : t
IHt1 : forall t2 : t, {le t1 t2} + {~ le t1 t2}
t2 : t
______________________________________(1/1)
{le (C t1) (C t2)} + {~ le (C t1) (C t2)}
归纳假设指的是
let2t2
,而我需要
let2t1

当我考虑这个问题时,它是有意义的,这个二元函数既不是第一个参数的原始递归函数,也不是第二个参数的原始递归函数,而是两个参数对的递归函数。我的印象是,我应该以某种方式同时对这两个论点进行归纳,但不知道如何做到这一点

我确实设法定义了一个布尔函数
leb
,并用它来证明
leu dec
,但从学习的角度来看,我想知道如何直接用归纳法进行证明

问题
  • 如何根据
    le
    的定义直接证明
    le_dec
    (即,不首先定义等价的布尔函数)
  • 最小可执行示例 主要定义 辅助引理 偏序的证明 等价布尔函数 基于
    Ltac自毁事件:=
    与对手重复比赛进球
    |H:存在124;-124;=>析构函数H
    |H:\uu/\\u124;-\ u=>自毁H
    结束;替代品。
    引理leu_dec_aux(t1 t2:t)(n:nat):
    高度t1+高度t2
    {le t1 t2}+{~le t1 t2}。
    证明。
    回复t1-t2。
    诱导n为[|n IH];简介t1 t2h。
    -破坏t1;H中的simple;欧米茄。
    -破坏t1,t2。
    +伊奥托使用了一种新方法。
    +清楚。正确的。对映介绍。依赖诱导对映体。
    应用le_规范形式,在第1页左边;替换:eauto。
    +清楚。正确的。对映介绍。依赖诱导对映体。
    应用le_规范形式,在第1页左边;替换:eauto。
    +清楚。正确的。对映介绍。依赖诱导对映体。
    应用le_规范形式_B_左相反1;自毁。奥托。
    +H中的simple。
    自毁(IH t1 t2);试试欧米茄。
    *伊奥托使用了一种新方法。
    *对。对映介绍。相反地应用le_倒装法。矛盾
    +清楚。正确的。对映介绍。依赖诱导对映体。
    应用le_规范形式_B_左相反1;自毁。奥托。
    +清楚。正确的。对映介绍。依赖诱导对映体。
    应用le_规范形式_C_左相反1;自毁。奥托。
    +清楚。正确的。对映介绍。依赖诱导对映体。
    应用le_规范形式_C_左相反1;自毁。奥托。
    +H中的simple。
    自毁(IH t2 t1);试试欧米茄。
    *伊奥托使用了一种新方法。
    *对。对映介绍。相反地应用le_倒装法。矛盾
    Qed。
    引理leu_dec'(t1 t2:t):
    {le t1 t2}+{~le t1 t2}。
    证明。
    自毁(高度t1+高度t2);自动的。
    Qed。
    
    与您用于定义
    leb
    功能的方法类似,您需要通过归纳元素高度来证明
    leu dec

    Lemma le_dec_aux t1 t2 n : height t1 + height t2 <= n -> {le t1 t2} + {~le t1 t2}.
    Proof.
    revert t1 t2.
    induction n as [|n IH].
    (* ... *)
    
    引理le_dec_aux t1 t2n:height t1+height t2{le t1 t2}+{~le t1 t2}。
    证明。
    回复t1-t2。
    诱导n为[| n IH]。
    (* ... *)
    

    也就是说,我认为用布尔函数证明可判定性是完全正确的。该库广泛使用此模式,使用专门的
    reflect
    谓词将一般命题连接到布尔计算,而不是
    sumbool
    类型
    {a}+{B}

    与您用于定义
    leb
    函数类似,您需要通过归纳元素高度来证明
    leu dec

    Lemma le_dec_aux t1 t2 n : height t1 + height t2 <= n -> {le t1 t2} + {~le t1 t2}.
    Proof.
    revert t1 t2.
    induction n as [|n IH].
    (* ... *)
    
    引理le_dec_aux t1 t2n:height t1+height t2{le t1 t2}+{~le t1 t2}。
    证明。
    回复t1-t2。
    诱导n为[| n IH]。
    (* ... *)
    

    也就是说,我认为用布尔函数证明可判定性是完全正确的。该库广泛使用此模式,使用专门的
    reflect
    谓词将一般命题连接到布尔计算,而不是
    sumbool
    类型
    {a}+{B}

    我尝试了@Arthur建议的版本,使用了有充分根据的递归。 这确实提供了一个很好的提取

    Definition rel p1 p2 := height_pair p1 < height_pair p2.
    
    Lemma rel_wf : well_founded rel.
    Proof.
      apply well_founded_ltof.
    Qed.
    
    Lemma le_dec (t1 t2 : t) :
      { le t1 t2 } + { ~le t1 t2 }.
    Proof.
      induction t1, t2 as [t1 t2]
        using (fun P => well_founded_induction_type_2 P rel_wf).
      destruct t1, t2;
        try (right; intros contra;
             (apply le_canonical_form_A_left in contra)
          || (apply le_canonical_form_B_left in contra; destruct contra)
          || (apply le_canonical_form_C_left in contra; destruct contra);
          discriminate).
      - left. apply le_A.
      - destruct (H t1 t2).
        + unfold rel, height_pair; simpl. omega.
        + left. apply le_B. assumption.
        + right. intros contra. apply le_inversion_B in contra. contradiction.
      - destruct (H t2 t1).
        + unfold rel, height_pair; simpl. omega.
        + left. apply le_C. assumption.
        + right. intros contra. apply le_inversion_C in contra. contradiction.
    Qed.
    
    Extraction Inline well_founded_induction_type_2 Fix_F_2.
      (* to have a nice extraction *)
    Extraction le_dec.
    

    我尝试了@Arthur建议的版本,使用了有充分根据的递归。 这确实提供了一个很好的提取

    Definition rel p1 p2 := height_pair p1 < height_pair p2.
    
    Lemma rel_wf : well_founded rel.
    Proof.
      apply well_founded_ltof.
    Qed.
    
    Lemma le_dec (t1 t2 : t) :
      { le t1 t2 } + { ~le t1 t2 }.
    Proof.
      induction t1, t2 as [t1 t2]
        using (fun P => well_founded_induction_type_2 P rel_wf).
      destruct t1, t2;
        try (right; intros contra;
             (apply le_canonical_form_A_left in contra)
          || (apply le_canonical_form_B_left in contra; destruct contra)
          || (apply le_canonical_form_C_left in contra; destruct contra);
          discriminate).
      - left. apply le_A.
      - destruct (H t1 t2).
        + unfold rel, height_pair; simpl. omega.
        + left. apply le_B. assumption.
        + right. intros contra. apply le_inversion_B in contra. contradiction.
      - destruct (H t2 t1).
        + unfold rel, height_pair; simpl. omega.
        + left. apply le_C. assumption.
        + right. intros contra. apply le_inversion_C in contra. contradiction.
    Qed.
    
    Extraction Inline well_founded_induction_type_2 Fix_F_2.
      (* to have a nice extraction *)
    Extraction le_dec.
    

    非常感谢你!现在我可以比较布尔函数和直接证明,我觉得它们的复杂度和开销相当。我还比较了提取的OCaml代码,有趣的是,生成的代码完全相同,只是
    le_dec
    首先执行了
    高度t1+高度t2的无用计算。因此,在实际需要计算关系是否成立的情况下,布尔函数有一个优势。如果要提取该函数,最好使用有充分基础的递归()对其进行编程。您仍然需要使用终止参数使函数被接受,但它不会干扰函数的计算行为。非常感谢!现在我可以比较布尔函数和直接证明,我觉得它们的复杂度和开销相当。我还比较了提取的OCaml代码,有趣的是,生成的代码完全相同,只是
    le_dec
    首先执行了
    高度t1+高度t2的无用计算。因此,在实际需要计算关系是否成立的情况下,布尔函数有一个优势。如果要提取该函数,最好使用有充分基础的递归()对其进行编程。你仍然需要使用一个小键盘
    
    Lemma le_dec (t1 t2 : t) :
      { le t1 t2 } + { ~le t1 t2 }.
    Proof.
      revert t2.
      induction t1; intros t2.
      - destruct t2.
        + eauto using le.
        + right. intro contra. dependent induction contra.
          apply le_canonical_form_A_left in contra1; subst. eauto.
        + right. intro contra. dependent induction contra.
          apply le_canonical_form_A_left in contra1; subst. eauto.
      - destruct t2.
        + right. intro contra. clear IHt1. dependent induction contra.
          apply le_canonical_form_B_left in contra1 as [? ?]; subst. eauto.
        + destruct IHt1 with t2.
          * eauto using le.
          * right. intro contra. apply le_inversion_B in contra. contradiction.
        + right; intro contra. clear IHt1. dependent induction contra.
          apply le_canonical_form_B_left in contra1 as [? ?]; subst. eauto.
      - destruct t2.
        + right. intro contra. clear IHt1. dependent induction contra.
          apply le_canonical_form_C_left in contra1 as [? ?]; subst. eauto.
        + right. intro contra. clear IHt1. dependent induction contra.
          apply le_canonical_form_C_left in contra1 as [? ?]; subst. eauto.
        + destruct IHt1 with t2.
          * admit. (* Wrong assumption *)
          * admit. (* Wrong assumption *)
    Restart.
      destruct (leb (t1, t2)) eqn:Heqn.
      - apply leb_to_le in Heqn. auto.
      - right. intro contra. apply le_to_leb in contra.
        rewrite Heqn in contra. discriminate.
    Qed.
    
    Ltac destruct_exs_conjs :=
      repeat match goal with
      | H : exists _, _ |- _ => destruct H
      | H : _ /\ _ |- _ => destruct H
      end; subst.
    
    Lemma le_dec_aux (t1 t2 : t) (n : nat) :
      height t1 + height t2 <= n ->
      {le t1 t2} + {~le t1 t2}.
    Proof.
      revert t1 t2.
      induction n as [| n IH]; intros t1 t2 H.
      - destruct t1; simpl in H; omega.
      - destruct t1, t2.
        + eauto using le.
        + clear. right. intro contra. dependent induction contra.
          apply le_canonical_form_A_left in contra1; subst. eauto.
        + clear. right. intro contra. dependent induction contra.
          apply le_canonical_form_A_left in contra1; subst. eauto.
        + clear. right. intro contra. dependent induction contra.
          apply le_canonical_form_B_left in contra1; destruct_exs_conjs. eauto.
        + simpl in H.
          destruct (IH t1 t2); try omega.
          * eauto using le.
          * right. intro contra. apply le_inversion_B in contra. contradiction.
        + clear. right. intro contra. dependent induction contra.
          apply le_canonical_form_B_left in contra1; destruct_exs_conjs. eauto.
        + clear. right. intro contra. dependent induction contra.
          apply le_canonical_form_C_left in contra1; destruct_exs_conjs. eauto.
        + clear. right. intro contra. dependent induction contra.
          apply le_canonical_form_C_left in contra1; destruct_exs_conjs. eauto.
        + simpl in H.
          destruct (IH t2 t1); try omega.
          * eauto using le.
          * right. intro contra. apply le_inversion_C in contra. contradiction.
    Qed.
    
    Lemma le_dec' (t1 t2 : t) :
      { le t1 t2 } + { ~le t1 t2 }.
    Proof.
      destruct (le_dec_aux t1 t2 (height t1 + height t2)); auto.
    Qed.
    
    Lemma le_dec_aux t1 t2 n : height t1 + height t2 <= n -> {le t1 t2} + {~le t1 t2}.
    Proof.
    revert t1 t2.
    induction n as [|n IH].
    (* ... *)
    
    Definition rel p1 p2 := height_pair p1 < height_pair p2.
    
    Lemma rel_wf : well_founded rel.
    Proof.
      apply well_founded_ltof.
    Qed.
    
    Lemma le_dec (t1 t2 : t) :
      { le t1 t2 } + { ~le t1 t2 }.
    Proof.
      induction t1, t2 as [t1 t2]
        using (fun P => well_founded_induction_type_2 P rel_wf).
      destruct t1, t2;
        try (right; intros contra;
             (apply le_canonical_form_A_left in contra)
          || (apply le_canonical_form_B_left in contra; destruct contra)
          || (apply le_canonical_form_C_left in contra; destruct contra);
          discriminate).
      - left. apply le_A.
      - destruct (H t1 t2).
        + unfold rel, height_pair; simpl. omega.
        + left. apply le_B. assumption.
        + right. intros contra. apply le_inversion_B in contra. contradiction.
      - destruct (H t2 t1).
        + unfold rel, height_pair; simpl. omega.
        + left. apply le_C. assumption.
        + right. intros contra. apply le_inversion_C in contra. contradiction.
    Qed.
    
    Extraction Inline well_founded_induction_type_2 Fix_F_2.
      (* to have a nice extraction *)
    Extraction le_dec.
    
    Lemma le_is_eq : forall t1 t2, le t1 t2 -> t1 = t2.
    Proof.
      intros.
      induction t1, t2 as [t1 t2]
        using (fun P => well_founded_induction_type_2 P rel_wf).
      destruct t1, t2;
        try ((apply le_canonical_form_A_left in H)
          || (apply le_canonical_form_B_left in H; destruct H)
          || (apply le_canonical_form_C_left in H; destruct H);
          discriminate).
      - reflexivity.
      - apply le_inversion_B in H.
        apply H0 in H.
        + congruence.
        + unfold rel, height_pair. simpl. omega.
      - apply le_inversion_C in H.
        apply H0 in H.
        + congruence.
        + unfold rel, height_pair. simpl. omega.
    Qed.