Skip to content

Instantly share code, notes, and snippets.

@JasonGross
Created February 5, 2014 19:47
Show Gist options
  • Select an option

  • Save JasonGross/8831581 to your computer and use it in GitHub Desktop.

Select an option

Save JasonGross/8831581 to your computer and use it in GitHub Desktop.
Ltac + typeclasses implementation of a partial split_sig tactic
(* Coq's build in tactics don't work so well with things like [iff]
so split them up into multiple hypotheses *)
Ltac split_in_context ident funl funr :=
repeat match goal with
| [ H : context p [ident] |- _ ] =>
let H0 := context p[funl] in let H0' := eval simpl in H0 in assert H0' by (apply H);
let H1 := context p[funr] in let H1' := eval simpl in H1 in assert H1' by (apply H);
clear H
end.
Ltac split_iff := split_in_context iff (fun a b : Prop => a -> b) (fun a b : Prop => b -> a).
Ltac split_and' :=
repeat match goal with
| [ H : ?a /\ ?b |- _ ] => destruct H
end.
Ltac split_and := split_and'; split_in_context and (fun a b : Type => a) (fun a b : Type => b).
Class can_transform_sigma A B := do_transform_sigma : A -> B.
Instance can_transform_sigT_base {A} {P : A -> Type}
: can_transform_sigma (sigT P) (sigT P) | 0
:= fun x => x.
Instance can_transform_sig_base {A} {P : A -> Prop}
: can_transform_sigma (sig P) (sig P) | 0
:= fun x => x.
Instance can_transform_sigT {A B B' C'}
`{forall x : A, can_transform_sigma (B x) (@sigT (B' x) (C' x))}
: can_transform_sigma (forall x : A, B x)
(@sigT (forall x, B' x) (fun b => forall x, C' x (b x))) | 0
:= fun f => existT
(fun b => forall x : A, C' x (b x))
(fun x => projT1 (do_transform_sigma (f x)))
(fun x => projT2 (do_transform_sigma (f x))).
Instance can_transform_sig {A B B' C'}
`{forall x : A, can_transform_sigma (B x) (@sig (B' x) (C' x))}
: can_transform_sigma (forall x : A, B x)
(@sig (forall x, B' x) (fun b => forall x, C' x (b x))) | 0
:= fun f => exist
(fun b => forall x : A, C' x (b x))
(fun x => proj1_sig (do_transform_sigma (f x)))
(fun x => proj2_sig (do_transform_sigma (f x))).
Ltac split_sig' :=
match goal with
| [ H : _ |- _ ]
=> let H' := fresh in
pose proof (@do_transform_sigma _ _ _ H) as H';
clear H;
destruct H'
end.
Ltac split_sig :=
repeat split_sig'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment