Timings for apartness.v
Require Import HoTT.Classes.interfaces.abstract_algebra.
Generalizable Variables A B C f g.
Lemma apart_ne x y : PropHolds (x ≶ y) -> PropHolds (x <> y).
#[export] Instance stable_eq_apartness: forall x y : A, Stable (x = y).
#[export]
Hint Extern 3 (PropHolds (_ <> _)) => eapply @apart_ne : typeclass_instances.
Lemma projected_strong_setoid `{IsApart B} `{Apart A} `{IsHSet A}
`{is_mere_relation A apart}
(f: A -> B)
(eq_correct : forall x y, x = y <-> f x = f y)
(apart_correct : forall x y, x ≶ y <-> f x ≶ f y)
: IsApart A.
apply apart_correct, symmetry, apart_correct.
apply apart_correct in ap.
apply (merely_destruct (cotransitive ap (f z))).
intros [?|?];apply tr;[left|right];apply apart_correct;assumption.
apply apart_correct;assumption.
apply apart_correct in ap;revert ap.
apply eq_correct;assumption.
Instance sg_apart_mere `{IsApart A} (P : A -> Type)
: is_mere_relation (sig P) apart.
Instance sig_strong_setoid `{IsApart A} (P: A -> Type) `{forall x, IsHProp (P x)}
: IsApart (sig P).
apply (projected_strong_setoid (@proj1 _ P)).
split;apply Sigma.equiv_path_sigma_hprop.
intros;apply reflexivity.
Context `{IsApart A} `{IsApart B} `{IsApart C}.
#[export] Instance strong_injective_injective `{!IsStrongInjective (f : A -> B)} :
IsInjective f.
pose proof (strong_injective_mor f).
apply strong_injective;auto.
(* If a morphism satisfies the binary strong extensionality property, it is
strongly extensional in both coordinates. *)
#[export] Instance strong_setoid_morphism_1
`{!StrongBinaryExtensionality (f : A -> B -> C)} :
forall z, StrongExtensionality (f z).
apply (merely_destruct (strong_binary_extensionality f z x z y E)).
destruct (irreflexivity (≶) z).
#[export] Instance strong_setoid_morphism_unary_2
`{!StrongBinaryExtensionality (f : A -> B -> C)} :
forall z, StrongExtensionality (fun x => f x z).
apply (merely_destruct (strong_binary_extensionality f x z y z E)).
destruct (irreflexivity (≶) z);assumption.
(* Conversely, if a morphism is strongly extensional in both coordinates, it
satisfies the binary strong extensionality property. We don't make this an
instance in order to avoid loops. *)
Lemma strong_binary_setoid_morphism_both_coordinates
`{!IsApart A} `{!IsApart B} `{!IsApart C} {f : A -> B -> C}
`{forall z, StrongExtensionality (f z)} `{forall z, StrongExtensionality (fun x => f x z)}
: StrongBinaryExtensionality f.
apply (merely_destruct (cotransitive E (f x₂ y₁))).
apply (strong_extensionality (fun x => f x y₁));trivial.
apply (strong_extensionality (f x₂));trivial.
Context `{IsApart A} `{IsApart B}.
Lemma strong_binary_setoid_morphism_commutative {f : A -> A -> B} `{!Commutative f}
`{forall z, StrongExtensionality (f z)} : StrongBinaryExtensionality f.
apply @strong_binary_setoid_morphism_both_coordinates;try exact _.
rewrite !(commutativity _ z).
apply (strong_extensionality (f z)).
Context `{DecidablePaths A}.
Instance default_apart : Apart A | 20
:= fun x y =>
match dec (x = y) with
| inl _ => false
| inr _ => true
end = true.
Typeclasses Opaque default_apart.
Instance default_apart_trivial : TrivialApart A (Aap:=default_apart).
unfold apart,default_apart.
intros x y;unfold apart,default_apart;split.
destruct (false_ne_true E).
intros E;destruct (dec (x=y)) as [e|_].
(* In case we have a decidable setoid, we can construct a strong setoid. Again
we do not make this an instance as it will cause loops *)
Context `{TrivialApart A} `{DecidablePaths A}.
(* Not Global in order to avoid loops *)
Instance ne_apart x y : PropHolds (x <> y) -> PropHolds (x ≶ y).
#[export] Instance dec_strong_setoid: IsApart A.
apply trivial_apart in ne.
intros e;apply ne,symmetry,e.
apply trivial_apart in ne.
destruct (dec (x=z)) as [e|ne'];[destruct (dec (z=y)) as [e'|ne']|].
destruct (dec (x=y));auto.
apply trivial_apart;trivial.
apply trivial_apart in nap.
(* And a similar result for morphisms *)
Section dec_setoid_morphisms.
Context `{IsApart A} `{!TrivialApart A} `{IsApart B}.
Instance dec_strong_morphism (f : A -> B) :
StrongExtensionality f.
apply tight_apart in E;auto.
Context `{!TrivialApart B}.
Instance dec_strong_injective (f : A -> B) `{!IsInjective f} :
IsStrongInjective f.
apply trivial_apart in ap.
Instance dec_strong_binary_morphism (f : A -> B -> C) :
StrongBinaryExtensionality f.
apply (merely_destruct (cotransitive hap (f x2 y1)));intros [h|h];apply tr.
apply tight_apart in h;auto.
exact (ap (fun x => f x y1) e).
apply tight_apart in h;auto.
End dec_setoid_morphisms.