rewrite
- это всего лишь сахаристый with
, который является просто оформленным совпадением «верхнего уровня». См. В Agda’s documentation.
Каковы некоторые из недостатков использования гетерогенного равенства, это не похоже, что большинство людей его любят. (Важно)
Это нормально
types-equal : ∀ {α} {A B : Set α} {x : A} {y : B} -> x ≅ y -> A ≡ B
types-equal refl = refl
это нормально, а также
A-is-Bool : {A : Set} {x : A} -> x ≅ true -> A ≡ Bool
A-is-Bool refl = refl
Это ошибка
fail : ∀ {n m} {i : Fin n} {j : Fin m} -> i ≅ j -> n ≡ m
fail refl = {!!}
-- n != m of type ℕ
-- when checking that the pattern refl has type i ≅ j
потому Fin n ≡ Fin m
не сразу следует n ≡ m
(вы можете ke это так, включив --injective-type-constructors
, но что makes Agda anti-classical) (Fin n ≡ Fin m -> n ≡ m
- provable).
Первоначально Agda допускается сопоставление с образцом на x ≅ y
когда x
и y
имеют не-unifiable типов, но это позволяет писать странные вещи, как (цитата из this нити)
P : Set -> Set
P S = Σ S (\s → s ≅ true)
pbool : P Bool
pbool = true , refl
¬pfin : ¬ P (Fin 2)
¬pfin (zero ,())
¬pfin (suc zero ,())
¬pfin (suc (suc()) ,())
tada : ¬ (Bool ≡ Fin 2)
tada eq = ⊥-elim (¬pfin (subst (\ S → P S) eq pbool))
Saizan или, может быть, это просто игнорируя типы и сравнивая имена конструкторов?
pigworker Saizan: это именно то, что я думаю, что происходит
Andread Авеля:
- Если я slighly изменить код, я могу доказать, Bool неравной Bool2, где true2, false2: Bool2 (см файл ..22.agda)
- Однако, если я переименую конструкторы в true, false: Bool2, то вдруг я не могу доказать, что Bool больше не равен Bool2 (см. другой файл). Итак, на данный момент Agda2 сравнивает яблоки и апельсины в определенных ситуациях. ;-)
Так что для того, чтобы соответствовать узор на i ≅ j
, где i : Fin n, j : Fin m
, в первую очередь необходимо унифицировать n
с m
OK : ∀ {n m} {i : Fin n} {j : Fin m} -> n ≡ m -> i ≅ j -> ...
OK refl refl = ...
Это главный недостаток heteregeneous равенства: необходимо предоставить доказательств равенства индексов всюду. Обычные cong
и subst
не индексируются, поэтому вам также необходимо предоставить индексированные версии (или использовать еще более раздражающие cong₂
и subst₂
).
Там нет таких проблем с «heteroindexed» (я не знаю, если он имеет имя собственное) равенство
data [_]_≅_ {ι α} {I : Set ι} {i} (A : I -> Set α) (x : A i) : ∀ {j} -> A j -> Set where
refl : [ A ] x ≅ x
например
OK : ∀ {n m} {i : Fin n} {j : Fin m} -> [ Fin ] i ≅ j -> n ≡ m
OK refl = refl
В более общем плане, когда у вас есть x : A i, y : A j, p : [ A ] x ≅ y
, вы можете матч узор на p
и j
будут объединены с i
, так что вам не нужно носить с собой дополнительное доказательство n ≡ m
.
Неоднородное равенство, представленное в Агда, также является inconsistent with the univalence axiom.
РЕДАКТИРОВАТЬ
шаблона согласования на x : A, y : B, x ≅ y
равно шаблон на A ≡ B
, а затем меняются каждый y
в контексте x
.Поэтому, когда вы пишете
fail : ∀ {n m} {i : Fin n} {j : Fin m} -> i ≅ j -> n ≡ m
fail refl = {!!}
это то же самое, как
fail' : ∀ {n m} {i : Fin n} {j : Fin m} -> Fin n ≡ Fin m -> i ≅ j -> n ≡ m
fail' refl refl = {!!}
, но вы не можете шаблон матч на Fin n ≡ Fin m
fail-coerce : ∀ {n m} -> Fin n ≡ Fin m -> Fin n -> Fin m
fail-coerce refl = {!!}
-- n != m of type ℕ
-- when checking that the pattern refl has type Fin n ≡ Fin m
, как вы не можете шаблон матча на
fail'' : ∀ {n m} -> Nat.pred n ≡ Nat.pred m -> n ≡ m
fail'' refl = {!!}
-- n != m of type ℕ
-- when checking that the pattern refl has type Nat.pred n ≡ Nat.pred m
Всего
f-inj : ∀ {n m} -> f n ≡ f m -> ...
f-inj refl = ...
работает только в том случае, если f
явно инъективен. То есть если f
представляет собой серию конструкторов (например, suc (suc n) ≡ suc (suc m)
) или вычисляет к ней (например, 2 + n ≡ 2 + m
). Конструкторы типов (которые Fin
) не являются инъективными, потому что это сделало бы Agda антиклассическим, поэтому вы не можете нарисовать на Fin n ≡ Fin m
, если вы не включите --injective-type-constructors
.
Индексы унифицировать для
data [_]_≅_ {ι α} {I : Set ι} {i} (A : I -> Set α) (x : A i) : ∀ {j} -> A j -> Set where
refl : [ A ] x ≅ x
, потому что вы не пытаетесь объединить A i
с A j
, но вместо того, чтобы явно нести индексы в типе [_]_≅_
, что делает их доступными для объединения. Когда индексы унифицированы, оба типа становятся одинаковыми A i
, и можно продолжить, как с пропозициональным равенством.
EDIT
Одна другая проблема с гетерогенной равенства является то, что она не полностью гетерогенная: в x : A, y : B, x ≅ y
A
и B
должны находиться в одной и той же вселенной. Лечение уровней вселенной в data
определений изменилось в последнее время, и теперь мы можем определить полностью гетерогенной равенство:
data _≅_ {α} {A : Set α} (x : A) : ∀ {β} {B : Set β} -> B -> Set where
refl : x ≅ x
Но это не работает
levels-equal : ∀ {α β} -> Set α ≅ Set β -> α ≅ β
levels-equal refl = refl
-- Refuse to solve heterogeneous constraint Set α : Set (suc α) =?=
-- Set β : Set (suc β)
потому что Agda не думает suc
инъективна
suc-inj : {α β : Level} -> suc α ≅ suc β -> α ≅ β
suc-inj refl = refl
-- α != β of type Level
-- when checking that the pattern refl has type suc α ≅ suc β
Если мы допускаем это, то мы можем доказать levels-equal
:
hcong : ∀ {α β δ} {A : Set α} {B : Set β} {D : Set δ} {x : A} {y : B}
-> (f : ∀ {γ} {C : Set γ} -> C -> D) -> x ≅ y -> f x ≅ f y
hcong f refl = refl
levelOf : ∀ {α} {A : Set α} -> A -> Level
levelOf {α} _ = α
postulate
suc-inj : {α β : Level} -> suc α ≅ suc β -> α ≅ β
levels-equal : ∀ {α β} -> Set α ≅ Set β -> α ≅ β
levels-equal p = suc-inj (suc-inj (hcong levelOf p))
Спасибо за быстрый ответ! Почему «тада» считается «странной»? Кроме того, 'fail' и' OK' кажутся почти идентичными, и я не уверен, почему перенос индексной функции 'A' объединяет индексы. Я имею в виду, что с гетеро-равенством мы знаем тип аргументов, поскольку он неявный, почему этого недостаточно для объединения индексов? –
@ Musa Al-hassy, 'tada' странно, потому что он сравнивает имена конструкторов разных типов. Это будет работать в LISP или PHP, но не на официальном языке. Если у вас есть 'C: D1' и' C: D2', нет смысла сравнивать один 'C' с другим - это разные вещи, даже если они выглядят одинаково. Я отредактировал ответ. – user3237465
woah; Я очень ценю ваши ответы. Я никогда не задумывался о том, как вещи унифицированы или переписаны. Я в основном играю с Agda по математике, а не по программированию, и редко сталкиваюсь с такими ошибками.Не могли бы вы сослаться на любые хорошие чтения, чтобы узнать больше о том, как Agda объединяет вещи и переписывает их. Благодаря! –