Built with
Alectryon. Bubbles (
) indicate interactive fragments: hover for details, tap to reveal contents. Use
Ctrl+↑ Ctrl+↓ to navigate,
Ctrl+🖱️ to focus. On Mac, use
⌘ instead of
Ctrl.
(** * Miscellaneous helper tactics for proving exponential laws *)
Require Import Category.Core Functor.Core NaturalTransformation.Core.
Require Import Functor.Paths NaturalTransformation.Paths.
Require Import HoTT.Tactics Basics.PathGroupoids Types.Forall Types.Prod.
(** These are probably more general than just exponential laws, but I haven't tried them more widely, yet. *)
(** Miscellaneous tactics to try *)
Ltac exp_laws_misc_t' :=
idtac;
match goal with
| _ => reflexivity
| _ => progress intros
| _ => progress simpl in *
| _ => apply (@path_forall _); intro
| _ => rewrite !identity_of
| _ => progress autorewrite with morphism
end.
(** Safe transformations to simplify complex types in the hypotheses or goal *)
Ltac exp_laws_simplify_types' :=
idtac;
match goal with
| [ H : (_ + _) |- _ ] => destruct H
| [ H : Unit |- _ ] => destruct H
| [ H : Empty |- _ ] => destruct H
| [ H : (_ * _) |- _ ] => destruct H
| [ |- _ = _ :> Functor _ _ ] => progress path_functor
| [ |- _ = _ :> NaturalTransformation _ _ ] => progress path_natural_transformation
| [ |- _ = _ :> prod _ _ ] => apply path_prod
end.
(** Do some simplifications of contractible types *)
Ltac exp_laws_handle_contr' :=
idtac;
match goal with
| [ H : Contr ?T, x : ?T |- _ ] => progress destruct (contr x)
| [ H : forall a, Contr (?T a), x : ?T _ |- _ ] => progress destruct (contr x)
| [ H : forall a b, Contr (?T a b), x : ?T _ _ |- _ ] => progress destruct (contr x)
| [ |- context[contr (center ?x)] ]
=> progress let H := fresh in
assert (H : idpath = contr (center x)) by exact (center _);
destruct H
end.
(** Try to simplify [transport] with some heuristics *)
Ltac exp_laws_handle_transport' :=
idtac;
match goal with
| _ => progress rewrite ?transport_forall_constant, ?path_forall_2_beta, ?transport_const, ?transport_path_prod
| [ |- context [path_functor_uncurried ?F ?G (?x; ?y)] ] (* https://coq.inria.fr/bugs/show_bug.cgi?id=3768 *)
=> rewrite (@path_functor_uncurried_fst _ _ _ F G x y)
| [ |- context[transport (fun y : Functor ?C ?D => ?f (y _0 ?x)%object)] ]
=> rewrite (fun a b => @transport_compose _ _ a b (fun y' => f (y' x)) (@object_of C D))
| [ |- context[transport (fun y : Functor ?C ?D => ?f (y _0 ?x)%object ?z)] ]
=> rewrite (fun a b => @transport_compose _ _ a b (fun y' => f (y' x) z) (@object_of C D))
| [ |- context[transport (fun y : Functor ?C ?D => ?f (y _0 ?x)%object ?z)] ]
=> rewrite (fun a b => @transport_compose _ _ a b (fun y' => f (y' x) z) (@object_of C D))
| [ |- context[transport (fun y : Functor ?C ?D => ?f (?g (y _0 ?x)%object))] ]
=> rewrite (fun a b => @transport_compose _ _ a b (fun y' => f (g (y' x))) (@object_of C D))
| [ |- context[transport (fun y : Functor ?C ?D => ?f (?g (y _0 ?x)%object) ?z)] ]
=> rewrite (fun a b => @transport_compose _ _ a b (fun y' => f (g (y' x)) z) (@object_of C D))
| _ => progress transport_path_forall_hammer
| [ |- context[components_of (transport ?P ?p ?z)] ]
=> simpl rewrite (@ap_transport _ P _ _ _ p (fun _ => components_of) z)
| [ |- context[object_of (transport ?P ?p ?z)] ]
=> simpl rewrite (@ap_transport _ P _ _ _ p (fun _ => object_of) z)
| [ |- context[morphism_of (transport ?P ?p ?z)] ]
=> simpl rewrite (@ap_transport _ P _ _ _ p (fun _ => morphism_of) z)
| [ |- context[fst (transport ?P ?p ?z)] ]
=> simpl rewrite (@ap_transport _ P _ _ _ p (fun _ => fst) z)
| [ |- context[snd (transport ?P ?p ?z)] ]
=> simpl rewrite (@ap_transport _ P _ _ _ p (fun _ => snd) z)
| [ |- context[pr1 (transport ?P ?p ?z)] ]
=> simpl rewrite (@ap_transport _ P _ _ _ p (fun _ => pr1) z)
end.
Ltac exp_laws_t' :=
first [ exp_laws_misc_t'
| exp_laws_simplify_types'
| exp_laws_handle_contr'
| exp_laws_handle_transport' ].
Ltac exp_laws_t := repeat exp_laws_t'.