使用 uniq 从 seq 通过 finType 派生 ssreflect finType
Derive a ssreflect finType from a seq over a finType with uniq
我有一个结构,由有限类型的序列和该序列的唯一性证明组成。这应该描述一个显然是有限的类型,但我不知道如何证明这一点。
我想我可以使用 UniqFinMixin,但是它需要——如果我理解正确的话——提供该类型所有元素的显式序列,我不知道如何计算。我尝试在有限类型上使用 Finite.enum,但它只生成一个包含有限类型所有元素的序列,我没有找到计算所有子序列/排列的优雅方法。
From mathcomp
Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq choice fintype.
From mathcomp
Require Import tuple finfun bigop finset.
Variable ft : finType.
Structure dbranch := {branch :> seq ft ; buniq : uniq branch}.
Canonical dbranch_subType := Eval hnf in [subType for branch].
Canonical dbranch_eqType := Eval hnf in EqType _ [eqMixin of dbranch by <:].
Canonical dbranch_choiceType := Eval hnf in ChoiceType _ [choiceMixin of dbranch by <:].
Canonical dbranch_countType := Eval hnf in CountType _ [countMixin of dbranch by <:].
Canonical dbranch_subCountType := Eval hnf in [subCountType of dbranch].
Lemma dbranchFin : Finite.mixin_of [eqType of dbranch].
Admitted. (* :-( *)
Canonical dbranch_finType := Eval hnf in FinType _ dbranchFin.
我觉得这里没有简单的方法来导出 finType,但我在 finset.v 文件中找不到它。预先感谢您的帮助。
您可以证明 dbranch
嵌入另一个 finType
——例如,ft
的元素列表类型,其大小受 #|ft|
限制。
Lemma size_dbranch d : size (branch d) < #|ft|.+1.
Proof.
rewrite ltnS [card]unlock uniq_leq_size ?buniq // => ?.
by rewrite mem_enum.
Qed.
Definition tag_of_dbranch d : {k : 'I_#|ft|.+1 & k.-tuple ft} :=
@Tagged _ (Sub (size (branch d)) (size_dbranch d))
(fun k : 'I_#|ft|.+1 => k.-tuple ft)
(in_tuple (branch d)).
Definition dbranch_of_tag (t : {k : 'I_#|ft|.+1 & k.-tuple ft}) : option dbranch :=
insub (val (tagged t)).
Lemma tag_of_dbranchK : pcancel tag_of_dbranch dbranch_of_tag.
Proof. by rewrite /tag_of_dbranch /dbranch_of_tag=> x; rewrite valK. Qed.
Definition dbranch_finMixin := PcanFinMixin tag_of_dbranchK.
Canonical dbranch_finType := Eval hnf in FinType dbranch dbranch_finMixin.
我有一个结构,由有限类型的序列和该序列的唯一性证明组成。这应该描述一个显然是有限的类型,但我不知道如何证明这一点。
我想我可以使用 UniqFinMixin,但是它需要——如果我理解正确的话——提供该类型所有元素的显式序列,我不知道如何计算。我尝试在有限类型上使用 Finite.enum,但它只生成一个包含有限类型所有元素的序列,我没有找到计算所有子序列/排列的优雅方法。
From mathcomp
Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq choice fintype.
From mathcomp
Require Import tuple finfun bigop finset.
Variable ft : finType.
Structure dbranch := {branch :> seq ft ; buniq : uniq branch}.
Canonical dbranch_subType := Eval hnf in [subType for branch].
Canonical dbranch_eqType := Eval hnf in EqType _ [eqMixin of dbranch by <:].
Canonical dbranch_choiceType := Eval hnf in ChoiceType _ [choiceMixin of dbranch by <:].
Canonical dbranch_countType := Eval hnf in CountType _ [countMixin of dbranch by <:].
Canonical dbranch_subCountType := Eval hnf in [subCountType of dbranch].
Lemma dbranchFin : Finite.mixin_of [eqType of dbranch].
Admitted. (* :-( *)
Canonical dbranch_finType := Eval hnf in FinType _ dbranchFin.
我觉得这里没有简单的方法来导出 finType,但我在 finset.v 文件中找不到它。预先感谢您的帮助。
您可以证明 dbranch
嵌入另一个 finType
——例如,ft
的元素列表类型,其大小受 #|ft|
限制。
Lemma size_dbranch d : size (branch d) < #|ft|.+1.
Proof.
rewrite ltnS [card]unlock uniq_leq_size ?buniq // => ?.
by rewrite mem_enum.
Qed.
Definition tag_of_dbranch d : {k : 'I_#|ft|.+1 & k.-tuple ft} :=
@Tagged _ (Sub (size (branch d)) (size_dbranch d))
(fun k : 'I_#|ft|.+1 => k.-tuple ft)
(in_tuple (branch d)).
Definition dbranch_of_tag (t : {k : 'I_#|ft|.+1 & k.-tuple ft}) : option dbranch :=
insub (val (tagged t)).
Lemma tag_of_dbranchK : pcancel tag_of_dbranch dbranch_of_tag.
Proof. by rewrite /tag_of_dbranch /dbranch_of_tag=> x; rewrite valK. Qed.
Definition dbranch_finMixin := PcanFinMixin tag_of_dbranchK.
Canonical dbranch_finType := Eval hnf in FinType dbranch dbranch_finMixin.