现有目标过早完成

时间:2018-07-13 21:22:23

标签: record coq typeclass coq-tactic

我有一个同时包含数据和公理的Class。我想基于(1)现有实例和(2)其他一些输入以证明模式构建另一个实例。我想在创建记录的新实例之前destruct进行第二次输入。

作为示例的最小Classjwiegley/category-theory中的一个缩水了:

Require Import Coq.Unicode.Utf8.
Require Import Coq.Init.Datatypes.
Require Import Coq.Classes.Morphisms.
Require Import Coq.Classes.SetoidDec.

Generalizable All Variables.

Reserved Infix "~>" (at level 90, right associativity).
Reserved Infix "∘" (at level 40, left associativity).

Record Category := {
  obj : Type;

  uhom := Type : Type;
  hom : obj -> obj -> uhom where "a ~> b" := (hom a b);
  homset :> ∀ X Y, Setoid (X ~> Y);

  compose {x y z} (f: y ~> z) (g : x ~> y) : x ~> z
    where "f ∘ g" := (compose f g);

  compose_respects x y z :>
    Proper (equiv ==> equiv ==> equiv) (@compose x y z);
}.

假设(2)是bool

Definition newCat (C : Category) (b : bool) : Category.
Proof.
  destruct b.
  - eapply Build_Category.
    Unshelve.

此时,objType填充:

  C : Category
  ============================
  ∀ x y z : Type, Proper (equiv ==> equiv ==> equiv) (?compose x y z)

subgoal 2 (ID 18) is:
 ∀ x y z : Type, (λ _ A : Type, A) y z → (λ _ A : Type, A) x y → (λ _ A : Type, A) x z

如果我删除了compose_respects公理(或者在不使用此字段的情况下使用了其他种类的Record),这种行为就会消失。如果将Category更改为Classobj将作为obj的{​​{1}}填写。似乎与类型类解析有关(C具有隐式类型类参数吗?)。

是否有办法防止这些(或任何!)变量被统一填充?最佳结果将是类似equiv + eapply的东西,根本不生成任何存在物,我可以按顺序将记录的字段作为子目标来填充。

1 个答案:

答案 0 :(得分:1)

看起来simple notypeclasses refine {| obj := _ |}可以解决问题。

  • {| obj := _|}是记录语法,用作Build_Category _ _ _ _ _的简写。
  • simple notypeclasses refine是一种战术。这是notypeclasses refine的变体,它不会搁置目标,也不会减少目标。
  • 可悲的是,与notypeclasses不同,没有通用的unshelve组合器。只有notypeclasses refinesimple notypeclasses refine

要进行调试,可以使用(未​​记录)Set Typeclasses Debug。这表明eapply Build_Category确实可以解析某些类型类,而refine {| obj := _|}更糟。

顺便说一句,我认为没有任何类型级别参数的Class Category是没有意义的-为什么您只想自动推断任何类别?