+ (* this actually has nothing to do with categories; it shows that proofs [|-A]//[|-B] are one-to-one with []//[A|-B] *)
+ (* TODO Lemma hom_functor_full*)
+
+ (* lemma: if a proof from no hypotheses contains no Brak's or Esc's, then the context contains no variables at level!=0 *)
+
+ (* In a tree of types, replace any type at level "lev" with None *)
+ Definition drop_lev {Γ}(lev:HaskLevel Γ)(tt:Tree ??(LeveledHaskType Γ ★)) : Tree ??(LeveledHaskType Γ ★) :=
+ mapTree (fun t => match t with
+ | Some (ttype @@ tlev) => if eqd_dec tlev lev then None else t
+ | _ => t
+ end) tt.
+ (* The opposite: replace any type which is NOT at level "lev" with None *)
+ Definition take_lev {Γ}(lev:HaskLevel Γ)(tt:Tree ??(LeveledHaskType Γ ★)) : Tree ??(HaskType Γ ★) :=
+ mapTree (fun t => match t with
+ | Some (ttype @@ tlev) => if eqd_dec tlev lev then Some ttype else None
+ | _ => None
+ end) tt.
+
+ (* In a tree of types, replace any type at depth "lev" or greater None *)
+ Definition drop_depth {Γ}(n:nat)(tt:Tree ??(LeveledHaskType Γ ★)) : Tree ??(LeveledHaskType Γ ★) :=
+ mapTree (fun t => match t with
+ | Some (ttype @@ tlev) => if eqd_dec (length tlev) n then None else t
+ | _ => t
+ end) tt.
+
+ (* delete from the tree any type which is NOT at level "lev" *)
+
+ Fixpoint take_lev' {Γ}(lev:HaskLevel Γ)(tt:Tree ??(LeveledHaskType Γ ★)) : ??(Tree ??(HaskType Γ ★)) :=
+ match tt with
+ | T_Leaf None => Some (T_Leaf None) (* FIXME: unsure of this; it ends up on both sides *)
+ | T_Branch b1 b2 =>
+ let b1' := take_lev' lev b1 in
+ let b2' := take_lev' lev b2 in
+ match b1' with
+ | None => b2'
+ | Some b1'' => match b2' with
+ | None => Some b1''
+ | Some b2'' => Some (b1'',,b2'')
+ end
+ end
+ | T_Leaf (Some (ttype@@tlev)) =>
+ if eqd_dec tlev lev
+ then Some [ttype]
+ else None
+ end.
+
+ Context (ga' : forall TV, TV ★ -> Tree ??(RawHaskType TV ★) -> Tree ??(RawHaskType TV ★) -> RawHaskType TV ★).
+
+ Definition ga : forall Γ, HaskTyVar Γ ★ -> Tree ??(HaskType Γ ★) -> Tree ??(HaskType Γ ★) -> HaskType Γ ★
+ := fun Γ ec ant suc =>
+ fun TV ite =>
+ ga'
+ TV
+ (ec TV ite)
+ (mapOptionTree (fun x => x TV ite) ant)
+ (mapOptionTree (fun x => x TV ite) suc).
+
+ Implicit Arguments ga [ [Γ] ].
+ Notation "a ~~~~> b" := (@ga _ _ a b) (at level 20).
+
+ Context (unit_type : forall TV, RawHaskType TV ★).
+
+ (*
+ * The story:
+ * - code types <[t]>@c become garrows c () t
+ * - free variables of type t at a level lev deeper than the succedent become garrows c () t
+ * - free variables at the level of the succedent become
+ *)
+ Fixpoint flatten_rawtype {TV}{κ}(depth:nat)(exp: RawHaskType TV κ) : RawHaskType TV κ :=
+ match exp with
+ | TVar _ x => TVar x
+ | TAll _ y => TAll _ (fun v => flatten_rawtype depth (y v))
+ | TApp _ _ x y => TApp (flatten_rawtype depth x) (flatten_rawtype depth y)
+ | TCon tc => TCon tc
+ | TCoerc _ t1 t2 t => TCoerc (flatten_rawtype depth t1) (flatten_rawtype depth t2) (flatten_rawtype depth t)
+ | TArrow => TArrow
+ | TCode v e => match depth with
+ | O => match v return RawHaskType TV ★ with
+ | TVar ★ ec => ga' TV ec [] [flatten_rawtype depth e]
+ | _ => unit_type TV
+ end
+ | (S depth') => TCode v (flatten_rawtype depth' e)
+ end
+ | TyFunApp tfc lt => TyFunApp tfc (flatten_rawtype_list _ depth lt)
+ end
+ with flatten_rawtype_list {TV}(lk:list Kind)(depth:nat)(exp:@RawHaskTypeList TV lk) : @RawHaskTypeList TV lk :=
+ match exp in @RawHaskTypeList _ LK return @RawHaskTypeList TV LK with
+ | TyFunApp_nil => TyFunApp_nil
+ | TyFunApp_cons κ kl t rest => TyFunApp_cons _ _ (flatten_rawtype depth t) (flatten_rawtype_list _ depth rest)
+ end.
+
+ Inductive AllT {T:Type}{P:T->Prop} : Tree ??T -> Prop :=
+ | allt_none : AllT []
+ | allt_some : forall t, P t -> AllT [t]
+ | allt_branch : forall b1 b2, AllT b1 -> AllT b2 -> AllT (b1,,b2)
+ .
+ Implicit Arguments AllT [[T]].
+
+ Definition getΓ (j:Judg) := match j with Γ > _ > _ |- _ => Γ end.
+
+ Definition getSuc (j:Judg) : Tree ??(LeveledHaskType (getΓ j) ★) :=
+ match j as J return Tree ??(LeveledHaskType (getΓ J) ★) with
+ Γ > _ > _ |- s => s
+ end.
+
+ Definition getlev {Γ}{κ}(lht:LeveledHaskType Γ κ) :=
+ match lht with t@@l => l end.
+
+ (* This tries to assign a single level to the entire succedent of a judgment. If the succedent has types from different
+ * levels (should not happen) it just picks one; if the succedent has no non-None leaves (also should not happen) it
+ * picks nil *)
+ Fixpoint getjlev {Γ}(tt:Tree ??(LeveledHaskType Γ ★)) : HaskLevel Γ :=
+ match tt with
+ | T_Leaf None => nil
+ | T_Leaf (Some (_ @@ lev)) => lev
+ | T_Branch b1 b2 =>
+ match getjlev b1 with
+ | nil => getjlev b2
+ | lev => lev
+ end
+ end.
+
+ (* an XJudg is a Judg for which the SUCCEDENT types all come from the same level, and that level is no deeper than "n" *)
+ (* even the empty succedent [] has a level... *)
+ Definition QJudg (n:nat)(j:Judg) := le (length (getjlev (getSuc j))) n.
+
+(* Definition qjudg2judg {n}(qj:QJudg n) : Judg := projT1 qj.*)
+
+ Inductive QRule : nat -> Tree ??Judg -> Tree ??Judg -> Type :=
+ mkQRule : forall n h c,
+ Rule h c ->
+ ITree _ (QJudg n) h ->
+ ITree _ (QJudg n) c ->
+ QRule n h c.
+
+ Definition QND n := ND (QRule n).
+
+ (*
+ * Any type "t" at a level with length "n" becomes (g () t)
+ * Any type "<[t]>" at a level with length "n-1" becomes (g () t)
+ *)
+
+ Definition flatten_type {Γ}(n:nat)(ht:HaskType Γ ★) : HaskType Γ ★ :=
+ fun TV ite =>
+ flatten_rawtype n (ht TV ite).
+
+ Definition minus' n m :=
+ match m with
+ | 0 => n
+ | _ => n - m
+ end.
+
+ (* to do: integrate this more cleanly with qjudg *)
+ Definition flatten_leveled_type {Γ}(n:nat)(ht:LeveledHaskType Γ ★) : LeveledHaskType Γ ★ :=
+ match ht with
+ htt @@ htlev =>
+ flatten_type (minus' n (length htlev)) htt @@ htlev
+ end.
+
+ Definition flatten_qjudg_ok (n:nat)(j:Judg) : Judg :=
+ match j with
+ Γ > Δ > ant |- suc =>
+ let ant' := mapOptionTree (flatten_leveled_type n) ant in
+ let suc' := mapOptionTree (flatten_leveled_type n) suc
+ in (Γ > Δ > ant' |- suc')
+ end.
+
+ Definition take_lev'' {Γ}(lev:HaskLevel Γ)(tt:Tree ??(LeveledHaskType Γ ★)) : Tree ??(HaskType Γ ★) :=
+ match (take_lev' lev tt) with
+ | None => []
+ | Some x => x
+ end.
+
+ Definition flatten_qjudg : forall (n:nat), Judg -> Judg.
+ refine (fun {n}{j} =>
+ match j as J return Judg with
+ Γ > Δ > ant |- suc =>
+ match getjlev suc with
+ | nil => flatten_qjudg_ok n j
+ | (ec::lev') => if eqd_dec (length lev') n
+ then let ant_host := drop_depth (S n) ant in
+ let ant_guest := take_lev (ec::lev') ant in (* FIXME: I want take_lev''!!!!! *)
+ (Γ > Δ > ant_host |- [ga ec ant_guest (mapOptionTree unlev suc) @@ lev'])
+ else flatten_qjudg_ok n j
+ end
+ end).
+ Defined.
+
+ Axiom literal_types_unchanged : forall n Γ l, flatten_type n (literalType l) = literalType(Γ:=Γ) l.
+
+ Lemma drop_depth_lemma : forall Γ (lev:HaskLevel Γ) x, drop_depth (length lev) [x @@ lev] = [].
+ admit.
+ Defined.
+
+ Lemma drop_depth_lemma_s : forall Γ (lev:HaskLevel Γ) ec x, drop_depth (S (length lev)) [x @@ (ec :: lev)] = [].
+ admit.
+ Defined.
+
+ Ltac drop_simplify :=
+ match goal with
+ | [ |- context[@drop_depth ?G (length ?L) [ ?X @@ ?L ] ] ] =>
+ rewrite (drop_depth_lemma G L X)
+ | [ |- context[@drop_depth ?G (S (length ?L)) [ ?X @@ (?E :: ?L) ] ] ] =>
+ rewrite (drop_depth_lemma_s G L E X)
+ | [ |- context[@drop_depth ?G ?N (?A,,?B)] ] =>
+ change (@drop_depth G N (A,,B)) with ((@drop_depth G N A),,(@drop_depth G N B))
+ | [ |- context[@drop_depth ?G ?N (T_Leaf None)] ] =>
+ change (@drop_depth G N (T_Leaf (@None (LeveledHaskType G ★)))) with (T_Leaf (@None (LeveledHaskType G ★)))
+ end.
+
+ Lemma take_lemma : forall Γ (lev:HaskLevel Γ) x, take_lev lev [x @@ lev] = [x].
+ admit.
+ Defined.
+
+ Ltac take_simplify :=
+ match goal with
+ | [ |- context[@take_lev ?G ?L [ ?X @@ ?L ] ] ] =>
+ rewrite (take_lemma G L X)
+ | [ |- context[@take_lev ?G ?N (?A,,?B)] ] =>
+ change (@take_lev G N (A,,B)) with ((@take_lev G N A),,(@take_lev G N B))
+ | [ |- context[@take_lev ?G ?N (T_Leaf None)] ] =>
+ change (@take_lev G N (T_Leaf (@None (LeveledHaskType G ★)))) with (T_Leaf (@None (LeveledHaskType G ★)))
+ end.
+
+ Class garrow :=
+ { ga_id : ∀ Γ Δ ec lev a , ND Rule [] [Γ > Δ > [] |- [@ga Γ ec a a @@ lev] ]
+ ; ga_comp : ∀ Γ Δ ec lev a b c, ND Rule [] [Γ > Δ > [@ga Γ ec a b @@ lev],,[@ga Γ ec b c @@ lev] |- [@ga Γ ec a c @@ lev] ]
+ ; ga_cancelr : ∀ Γ Δ ec lev a , ND Rule [] [Γ > Δ > [] |- [@ga Γ ec (a,,[]) a @@ lev] ]
+ ; ga_cancell : ∀ Γ Δ ec lev a , ND Rule [] [Γ > Δ > [] |- [@ga Γ ec ([],,a) a @@ lev] ]
+ ; ga_uncancelr : ∀ Γ Δ ec lev a , ND Rule [] [Γ > Δ > [] |- [@ga Γ ec a (a,,[]) @@ lev] ]
+ ; ga_uncancell : ∀ Γ Δ ec lev a , ND Rule [] [Γ > Δ > [] |- [@ga Γ ec a ([],,a) @@ lev] ]
+ ; ga_assoc : ∀ Γ Δ ec lev a b c, ND Rule [] [Γ > Δ > [] |- [@ga Γ ec ((a,,b),,c) (a,,(b,,c)) @@ lev] ]
+ ; ga_unassoc : ∀ Γ Δ ec lev a b c, ND Rule [] [Γ > Δ > [] |- [@ga Γ ec (a,,(b,,c)) ((a,,b),,c) @@ lev] ]
+ ; ga_swap : ∀ Γ Δ ec lev a b , ND Rule [] [Γ > Δ > [] |- [@ga Γ ec (a,,b) (b,,a) @@ lev] ]
+ ; ga_drop : ∀ Γ Δ ec lev a , ND Rule [] [Γ > Δ > [] |- [@ga Γ ec a [] @@ lev] ]
+ ; ga_copy : ∀ Γ Δ ec lev a , ND Rule [] [Γ > Δ > [] |- [@ga Γ ec a (a,,a) @@ lev] ]
+ ; ga_first : ∀ Γ Δ ec lev a b x, ND Rule [] [Γ > Δ > [@ga Γ ec a b @@ lev] |- [@ga Γ ec (a,,x) (b,,x) @@ lev] ]
+ ; ga_second : ∀ Γ Δ ec lev a b x, ND Rule [] [Γ > Δ > [@ga Γ ec a b @@ lev] |- [@ga Γ ec (x,,a) (x,,b) @@ lev] ]
+ ; ga_lit : ∀ Γ Δ ec lev lit , ND Rule [] [Γ > Δ > [] |- [@ga Γ ec [] [literalType lit] @@ lev] ]
+ ; ga_curry : ∀ Γ Δ ec lev a b c, ND Rule [] [Γ > Δ > [@ga Γ ec (a,,[b]) [c] @@ lev] |- [@ga Γ ec a [b ---> c] @@ lev] ]
+ ; ga_apply : ∀ Γ Δ ec lev a a' b c, ND Rule [] [Γ > Δ >
+ [@ga Γ ec a [b ---> c] @@ lev],,[@ga Γ ec a' [b] @@ lev]
+ |-
+ [@ga Γ ec (a,,a') [c] @@ lev] ]
+ }.
+
+ Context (gar:garrow).
+
+ Definition boost : forall Γ Δ ant x y,
+ ND Rule [] [ Γ > Δ > x |- y ] ->
+ ND Rule [ Γ > Δ > ant |- x ] [ Γ > Δ > ant |- y ].
+ admit.
+ Defined.
+ Definition postcompose : ∀ Γ Δ ec lev a b c,
+ ND Rule [] [ Γ > Δ > [] |- [@ga Γ ec a b @@ lev] ] ->
+ ND Rule [] [ Γ > Δ > [@ga Γ ec b c @@ lev] |- [@ga Γ ec a c @@ lev] ].
+ admit.
+ Defined.
+ Definition precompose : ∀ Γ Δ lev a b c x,
+ ND Rule [] [ Γ > Δ > a |- x,,[b @@ lev] ] ->
+ ND Rule [] [ Γ > Δ > [b @@ lev] |- [c @@ lev] ] ->
+ ND Rule [] [ Γ > Δ > a,,x |- [c @@ lev] ].
+ admit.
+ Defined.
+
+ Set Printing Width 130.
+
+ Definition garrowfy_arrangement' :
+ forall Γ (Δ:CoercionEnv Γ)
+ (ec:HaskTyVar Γ ★) (lev:HaskLevel Γ) (ant1 ant2:Tree ??(LeveledHaskType Γ ★)) (r:Arrange ant1 ant2),
+ ND Rule [] [Γ > Δ > [] |- [@ga _ ec (take_lev (ec :: lev) ant2) (take_lev (ec :: lev) ant1) @@ lev] ].
+
+ intros Γ Δ ec lev.
+ refine (fix garrowfy ant1 ant2 (r:Arrange ant1 ant2):
+ ND Rule [] [Γ > Δ > [] |- [@ga _ ec (take_lev (ec :: lev) ant2) (take_lev (ec :: lev) ant1) @@ lev]] :=
+ match r as R in Arrange A B return
+ ND Rule [] [Γ > Δ > [] |- [@ga _ ec (take_lev (ec :: lev) B) (take_lev (ec :: lev) A) @@ lev]]
+ with
+ | RCanL a => let case_RCanL := tt in ga_uncancell _ _ _ _ _
+ | RCanR a => let case_RCanR := tt in ga_uncancelr _ _ _ _ _
+ | RuCanL a => let case_RuCanL := tt in ga_cancell _ _ _ _ _
+ | RuCanR a => let case_RuCanR := tt in ga_cancelr _ _ _ _ _
+ | RAssoc a b c => let case_RAssoc := tt in ga_assoc _ _ _ _ _ _ _
+ | RCossa a b c => let case_RCossa := tt in ga_unassoc _ _ _ _ _ _ _
+ | RExch a b => let case_RExch := tt in ga_swap _ _ _ _ _ _
+ | RWeak a => let case_RWeak := tt in ga_drop _ _ _ _ _
+ | RCont a => let case_RCont := tt in ga_copy _ _ _ _ _
+ | RLeft a b c r' => let case_RLeft := tt in garrowfy _ _ r' ;; boost _ _ _ _ _ (ga_second _ _ _ _ _ _ _)
+ | RRight a b c r' => let case_RRight := tt in garrowfy _ _ r' ;; boost _ _ _ _ _ (ga_first _ _ _ _ _ _ _)
+ | RComp a b c r1 r2 => let case_RComp := tt in (fun r1' r2' => _) (garrowfy _ _ r1) (garrowfy _ _ r2)
+ end); clear garrowfy; repeat take_simplify; repeat drop_simplify; intros.
+
+ destruct case_RComp.
+ (*
+ set (ga_comp Γ Δ ec lev (``c) (``b) (``a)) as q.
+ eapply precompose.
+ Focus 2.
+ apply q.
+ refine ( _ ;; boost _ _ _ _ _ (ga_comp _ _ _ _ _ _ _)).
+ apply precompose.
+ Focus 2.
+ eapply ga_comp.
+ *)
+ admit.
+ Defined.
+
+ Definition garrowfy_arrangement :
+ forall Γ (Δ:CoercionEnv Γ) n
+ (ec:HaskTyVar Γ ★) (lev:HaskLevel Γ) (ant1 ant2:Tree ??(LeveledHaskType Γ ★)) (r:Arrange ant1 ant2) succ,
+ (*ec :: lev = getjlev succ ->*)
+ (* H0 : left (Datatypes.length lev ≠ n) e = Peano_dec.eq_nat_dec (Datatypes.length lev) n *)
+ ND Rule
+ [Γ > Δ > drop_depth n ant1 |- [@ga _ ec (take_lev (ec :: lev) ant1) (mapOptionTree unlev succ) @@ lev]]
+ [Γ > Δ > drop_depth n ant2 |- [@ga _ ec (take_lev (ec :: lev) ant2) (mapOptionTree unlev succ) @@ lev]].
+ intros.
+ refine ( _ ;; (boost _ _ _ _ _ (postcompose _ _ _ _ _ _ _ (garrowfy_arrangement' Γ Δ ec lev ant1 ant2 r)))).
+ apply nd_rule.
+ apply RArrange.
+ refine ((fix garrowfy ant1 ant2 (r:Arrange ant1 ant2) :=
+ match r as R in Arrange A B return Arrange (drop_depth _ A) (drop_depth _ B) with
+ | RCanL a => let case_RCanL := tt in RCanL _
+ | RCanR a => let case_RCanR := tt in RCanR _
+ | RuCanL a => let case_RuCanL := tt in RuCanL _
+ | RuCanR a => let case_RuCanR := tt in RuCanR _
+ | RAssoc a b c => let case_RAssoc := tt in RAssoc _ _ _
+ | RCossa a b c => let case_RCossa := tt in RCossa _ _ _
+ | RExch a b => let case_RExch := tt in RExch _ _
+ | RWeak a => let case_RWeak := tt in RWeak _
+ | RCont a => let case_RCont := tt in RCont _
+ | RLeft a b c r' => let case_RLeft := tt in RLeft _ (garrowfy _ _ r')
+ | RRight a b c r' => let case_RRight := tt in RRight _ (garrowfy _ _ r')
+ | RComp a b c r1 r2 => let case_RComp := tt in RComp (garrowfy _ _ r1) (garrowfy _ _ r2)
+ end) ant1 ant2 r); clear garrowfy; repeat take_simplify; repeat drop_simplify; intros.
+ Defined.