我有一个二进制数表示,加上一些转换为Nat:
open import Data.Nat
open import Data.Nat.Properties
open import Function
open import Relation.Binary.PropositionalEquality hiding (trans; cong; subst; sym)
open import Relation.Binary.HeterogeneousEquality
open import Data.Unit
open import Algebra
module CS = CommutativeSemiring commutativeSemiring
data Bin : ℕ → Set where
zero : Bin zero
2*n : ∀ {n} → Bin n → Bin (n + n)
2*n+1 : ∀ {n} → Bin n → Bin (suc (n + n))
suc-lem : ∀ n → suc (suc (n + n)) ≡ suc n + suc n
suc-lem zero = refl
suc-lem (suc n) rewrite
CS.+-comm n (suc n)
| suc-lem n | CS.+-comm n (suc (suc n))
| CS.+-comm n (suc n) = refl
inc : ∀ {n} → Bin n → Bin (suc n)
inc zero = 2*n+1 zero
inc (2*n b) = 2*n+1 b
inc (2*n+1 {n} b) rewrite suc-lem n = 2*n (inc b)
nat2bin : (n : ℕ) → Bin n
nat2bin zero = zero
nat2bin (suc n) = inc (nat2bin n)
bin2nat : ∀ {n} → Bin n → ℕ
bin2nat {n} b = n
我认为我需要异质平等来证明这里的事情,因为两个Bin-s的Nat指数通常并不明显。我虽然在阿格达缺乏经验,所以请告诉我这种方法是否被误导。
我坚持以下内容:
lem : ∀ n → 2*n+1 (inc (nat2bin n)) ≅ inc (inc (2*n+1 (nat2bin n)))
lem zero = refl
lem (suc n) =
subst
(λ b → 2*n+1 (inc (inc (nat2bin n))) ≅ inc (inc b))
(sym $ lem ?) ?
显而易见的是将n
插入sym $ lem ?
,但这会导致错误抱怨suc (n + n) != n + suc n
。
我想知道为什么会发生这种情况或者如何帮助它。
答案 0 :(得分:4)
进口:
open import Level hiding (zero; suc)
open import Function
open import Relation.Binary.HeterogeneousEquality
renaming (sym to hsym; trans to htrans; cong to hcong; subst to hsubst)
open import Relation.Binary.PropositionalEquality
open import Data.Nat
open import Data.Fin hiding (_+_)
open import Algebra
open import Data.Nat.Properties
module ℕplus = CommutativeSemiring commutativeSemiring
我已经重新安排了你的inc
以简化一些事情:
inc : ∀ {n} → Bin n → Bin (suc n)
inc zero = 2*n+1 zero
inc (2*n b) = 2*n+1 b
inc (2*n+1 {n} b) = subst (Bin ∘ suc) (ℕplus.+-comm n (suc n)) (2*n (inc b))
引理:
lem : ∀ n → 2*n+1 (inc (nat2bin n)) ≅ inc (inc (2*n+1 (nat2bin n)))
lem zero = refl
lem (suc n) = {!!}
洞的类型是
2*n+1 (inc (inc (nat2bin n))) ≅
inc
(subst ((λ {.x} → Bin) ∘ suc) (ℕplus.+-comm (suc n) (suc (suc n)))
(2*n (inc (inc (nat2bin n)))))
所以我们需要从标准库中删除可替换的东西:
≡-subst-removable : ∀ {a p} {A : Set a}
(P : A → Set p) {x y} (eq : x ≡ y) z →
P.subst P eq z ≅ z
≡-subst-removable P refl z = refl
的类型
hsym $
≡-subst-removable
(Bin ∘ suc)
(ℕplus.+-comm (suc n) (suc (suc n)))
(2*n $ inc $ inc $ nat2bin n)
是
(2*n $ inc $ inc $ nat2bin n) ≅
subst ((λ {.x} → Bin) ∘ suc) (ℕplus.+-comm (suc n) (suc (suc n)))
(2*n $ inc $ inc $ nat2bin n)
几乎我们需要什么。现在我们要添加hcong inc
,但编译器会拒绝它。
以下是cong
的实现:
cong : ∀ {a b} {A : Set a} {B : A → Set b} {x y}
(f : (x : A) → B x) → x ≅ y → f x ≅ f y
cong f refl = refl
因此x
和y
必须属于同一类型A
,而我们的subst
会更改类型。
以下是hcong
的实现,我们需要:
hcong' : {α β γ : Level} {I : Set α} {i j : I}
-> (A : I -> Set β) {B : {k : I} -> A k -> Set γ} {x : A i} {y : A j}
-> i ≡ j
-> (f : {k : I} -> (x : A k) -> B x)
-> x ≅ y
-> f x ≅ f y
hcong' _ refl _ refl = refl
最后的证明:
lem : ∀ n → 2*n+1 (inc (nat2bin n)) ≅ inc (inc (2*n+1 (nat2bin n)))
lem zero = refl
lem (suc n) =
hcong'
(Bin ∘ suc)
(ℕplus.+-comm (suc n) (suc (suc n)))
inc
$ hsym
$ ≡-subst-removable
(Bin ∘ suc)
(ℕplus.+-comm (suc n) (suc (suc n)))
(2*n $ inc $ inc $ nat2bin n)
此外,我们可以合并subst-removable
和cong
:
≡-cong-subst-removable : {α β γ : Level} {I : Set α} {i j : I}
-> (A : I -> Set β) {B : {k : I} -> A k -> Set γ}
-> (e : i ≡ j)
-> (x : A i)
-> (f : {k : I} -> (x : A k) -> B x)
-> f (subst A e x) ≅ f x
≡-cong-subst-removable _ refl _ _ = refl
lem' : ∀ n → 2*n+1 (inc (nat2bin n)) ≅ inc (inc (2*n+1 (nat2bin n)))
lem' zero = refl
lem' (suc n) = hsym $
≡-cong-subst-removable
(Bin ∘ suc)
(ℕplus.+-comm (suc n) (suc (suc n)))
(2*n $ inc $ inc $ nat2bin n)
inc
BTW,Pierce意味着这个数据类型,我想:
data Bin : Set where
zero : Bin
2*n : Bin → Bin
2*n+1 : Bin → Bin
BTW2,可以在没有其他定义的情况下证明你的设计实例:
contrived-example : {n : ℕ} {f : Fin (n + suc n)}
-> f ≅ fromℕ (n + suc n)
-> f ≅ fromℕ (suc n + n)
contrived-example {n} eq = htrans eq $ hcong fromℕ $ ≡-to-≅ $ ℕplus.+-comm n (suc n)
BTW3,hsubst-ix1可以减少很多,因为你使用异构相等而不需要证明类型相等:
hsubst' : {C1 C2 : Set} {x : C1} {y : C2}
-> (P : {C : Set} -> C -> Set)
-> x ≅ y
-> P x
-> P y
hsubst' _ refl x = x
contrived-example' :
∀ n
→ (f : Fin (n + suc n))
→ (fromℕ (n + suc n) ≅ fromℕ (suc n + n))
→ (f ≅ fromℕ (n + suc n))
→ (f ≅ fromℕ (suc n + n))
contrived-example' n f eq p = hsubst' (λ f' → f ≅ f') eq p
答案 1 :(得分:2)
事实证明,这个问题有点类似this one,除了这里的内射型构造函数没有帮助。
通常情况下,当明确平等两侧的两种类型相等时,您可以使用subst
进行异构平等:
hsubst :
{A : Set}
(P : A → Set)
{x x' : A}
→ x ≅ x'
→ P x
→ P x'
hsubst P refl p = p
这个hsubst
与命题相等的subst
几乎相同,除了相等的类型。由于我们需要知道x
和x'
的类型是相等的,我们可以将我们的异构相等证明转换为普通证明,然后使用常规subst
。< / p>
然而,OP(即我)试图使用在两边都有索引类型的相等来替换,并且指数相等并不明显。解决方案是通过索引对hsubst
进行参数化,并要求为索引提供额外的相等证明:
hsubst-ix1 :
{I : Set}
(C : I → Set)
(P : ∀ {i} → C i → Set)
{i i' : I}
{x : C i}
{x' : C i'}
→ i ≡ i'
→ x ≅ x'
→ P x
→ P x'
hsubst-ix1 C P refl refl p = p
我进行了一些实验,以找出可以推断出哪些参数,结果如上所述。这是一个人为的例子:
open import Relation.Binary.HeterogeneousEquality hiding (cong)
open import Relation.Binary.PropositionalEquality
open import Data.Nat
open import Data.Fin hiding (_+_)
open import Algebra
open import Data.Nat.Properties
module ℕplus = CommutativeSemiring commutativeSemiring
contrived-example :
∀ n
→ (f : Fin (n + suc n))
→ (fromℕ (n + suc n) ≅ fromℕ (suc n + n))
→ (f ≅ fromℕ (n + suc n))
→ (f ≅ fromℕ (suc n + n))
contrived-example n f eq p =
hsubst-ix1
-- the type constructor to be indexed
Fin
-- substitution
(λ f' → f ≅ f')
-- proof that the indices are equal
(cong suc (ℕplus.+-comm n (suc n)))
-- heterogeneous equality
eq
-- original expression
p