Created
December 20, 2021 09:14
-
-
Save MarisaKirisame/54c17447ed5aac8aebdc79faaac29a25 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Require Export List FunctionalExtensionality. | |
Set Implicit Arguments. | |
Ltac get_goal := match goal with |- ?x => x end. | |
Ltac get_match H F := match H with context [match ?n with _ => _ end] => F n end. | |
Ltac get_matches F := | |
match goal with | |
| [ |- ?X ] => get_match X F | |
| [ H : ?X |- _ ] => get_match X F | |
end. | |
Definition channel P NT (N : NT) : Type := P. | |
Arguments channel : simpl never. | |
Inductive sandbox_closer : Prop := ms : sandbox_closer -> sandbox_closer. | |
Definition sandbox_closer_exit : sandbox_closer -> False := ltac:(induction 1; trivial). | |
Ltac set_result N T := match goal with | _ := ?X : channel _ N |- _ => unify X T end. | |
Ltac get_result N := match goal with | _ := ?X : channel _ N |- _ => X end. | |
Ltac clear_result N := match goal with | H := _ : channel _ N |- _ => clear H end. | |
Ltac make_sandbox T N := | |
let f := fresh in | |
let g := get_goal in | |
let H := fresh in | |
evar (f : channel T N); assert(sandbox_closer -> g) as H; [intro | clear H]. | |
Ltac exit_sandbox := | |
exfalso; | |
match goal with | |
| X : sandbox_closer |- _ => apply sandbox_closer_exit in X; tauto | |
end. | |
Inductive Tree := | |
| Empty | |
| Node : Tree -> Tree -> Tree. | |
Notation "[ a , b ]" := (Node a b). | |
Notation "0" := Empty. | |
Definition Combine_helper (T1 T2 T3 T4 T5 T6 T7 : Tree) : Tree := | |
match (T1, T2, T3, T4) with | |
| (0, 0, 0, 0) => | |
match T5 with | |
| Node T5a T5b => [[[[0, T7], T6], T5a], T5b] | |
| 0 => | |
match T6 with | |
| Node _ _ => [[[[[T6, T7], 0], 0], 0], 0] | |
| 0 => | |
match T7 with | |
| [[[[T7a, T7b], T7c], T7d], T7e] => | |
[[[[[0, T7a], T7b], T7c], T7d], T7e] | |
| _ => T7 | |
end | |
end | |
end | |
| _ => [[[[[[T7, T6], T5], T4], T3], T2], T1] | |
end. | |
Definition Combine X := | |
match X with (t1, t2, t3, t4, t5, t6, t7) => Combine_helper t1 t2 t3 t4 t5 t6 t7 end. | |
Ltac l T := unify T Empty; simpl in *. | |
Ltac r T := | |
let lt := fresh in | |
let rt := fresh in | |
evar (lt : Tree); evar (rt : Tree); | |
unify T (Node lt rt); simpl in *. | |
Ltac act := let res := get_match ltac:(get_goal) ltac:(fun x => x) in l res + r res. | |
Ltac prepare_work := repeat econstructor; compute. | |
Ltac work := | |
prepare_work; | |
solve [repeat (trivial; compute; act)]. | |
Ltac get_destruct_next N := | |
prepare_work; | |
repeat act; repeat f_equal; | |
match goal with | |
|- _ = ?X => is_var X; try set_result N X | |
end. | |
Ltac detect_destruct := | |
make_sandbox Tree tt; | |
[ | |
get_destruct_next tt; | |
repeat match get_goal with context [?t] => is_evar t; l t end; | |
exit_sandbox| | |
]; | |
let ret := get_result tt in destruct ret; | |
clear_result tt. | |
Definition Split_helper(T : Tree) : | |
{ T1 : Tree & | |
{ T2 : Tree & | |
{ T3 : Tree & | |
{ T4 : Tree & | |
{ T5 : Tree & | |
{ T6 : Tree & | |
{ T7 : Tree | Combine_helper T1 T2 T3 T4 T5 T6 T7 = T } } } } } } }. | |
repeat (work||detect_destruct). | |
Defined. | |
Definition Split(T : Tree) : Tree * Tree * Tree * Tree * Tree * Tree * Tree := | |
match Split_helper T with | |
| existT _ T1 (existT _ T2 (existT _ T3 | |
(existT _ T4 (existT _ T5 (existT _ T6 (exist _ T7 _)))))) => | |
(T1, T2, T3, T4, T5, T6, T7) | |
end. | |
Goal forall t, Combine (Split t) = t. | |
intros; unfold Split, Combine. | |
destruct Split_helper as [? [? [? [? [? [? []]]]]]]; subst. | |
simpl in *; trivial. | |
Qed. | |
Ltac no_inner_match_smart_destruct T := | |
(is_var T; destruct T) || | |
(let F := fresh in destruct T eqn:?F; | |
match type of F with ?Term = _ => let F' x := fail 3 in try get_match Term F' end; | |
match type of F with ?Term = _ :> {_} + {_} => clear F | _ => idtac end). | |
Ltac match_type_destruct T := | |
get_matches ltac:(fun x => match type of x with T => no_inner_match_smart_destruct x end). | |
Ltac invcs H := inversion H; clear H; subst. | |
Goal forall t, Split (Combine t) = t. | |
intros. | |
destruct t as [[[[[[]]]]]]. | |
unfold Split; destruct Split_helper as [? [? [? [? [? [? []]]]]]]. | |
unfold Combine, Combine_helper in *. | |
repeat ( | |
simpl in *; | |
trivial; | |
match_type_destruct Tree|| | |
discriminate|| | |
match goal with | |
| H : _ = _ : Tree |- _ => invcs H | |
end|| | |
subst). | |
Qed. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment