module Core.Var import Core.Context import Core.Thinning %prefix_record_projections off -- Variables ------------------------------------------------------------------- data IsVar : Nat -> Context -> Type where Here : IsVar 0 (sx :< n) There : IsVar k sx -> IsVar (S k) (sx :< n) export record Var (sx : Context) where constructor MakeVar index : Nat 0 prf : IsVar index sx %name IsVar prf %name Var i, j, k -- Constructors ---------------------------------------------------------------- export here : Var (sx :< n) here = MakeVar 0 Here export there : Var sx -> Var (sx :< n) there (MakeVar index prf) = MakeVar (S index) (There prf) -- Views ----------------------------------------------------------------------- namespace View public export data View : Var sx -> Type where Here : View Core.Var.here There : (i : Var sx) -> View (there i) %name View.View view export view : (i : Var sx) -> View i view (MakeVar 0 Here) = Here view (MakeVar (S k) (There prf)) = There (MakeVar k prf) -- Views are Unique viewInverse : {0 i : Var sx} -> View i -> Var sx viewInverse Here = here viewInverse (There i) = there i viewInversePrf1 : (view : View i) -> viewInverse view = i viewInversePrf1 Here = Refl viewInversePrf1 (There i) = Refl viewInversePrf2 : {0 i : Var sx} -> (v : View i) -> view (viewInverse v) = (rewrite viewInversePrf1 v in v) viewInversePrf2 Here = Refl viewInversePrf2 (There (MakeVar index prf)) = Refl export viewUnique : {0 i : Var sx} -> (view1, view2 : View i) -> view1 = view2 viewUnique view1 view2 = rewrite sym $ viewInversePrf2 view1 in rewrite sym $ viewInversePrf2 view2 in rewrite viewInversePrf1 view1 in rewrite viewInversePrf1 view2 in Refl -- Weakening ------------------------------------------------------------------- doWkn : Var sx -> {0 thin : sx `Thins` sy} -> View thin -> Var sy doWkn' : {0 i : Var (sx :< n)} -> View i -> sx `Thins` sy -> Var (sy :< n) doWkn i (Id sy) = i doWkn i (Drop thin n) = there $ doWkn i (view thin) doWkn i (Keep thin n) = doWkn' (view i) thin doWkn' Here thin = here doWkn' (There i) thin = there $ doWkn i (view thin) export wkn : Var sx -> sx `Thins` sy -> Var sy wkn i thin = doWkn i (view thin) -- Is Homomorphic export doWknHomo : (i : Var sx) -> {thin1 : sx `Thins` sy} -> {thin2 : sy `Thins` sz} -> (view1 : View thin1) -> (view2 : View thin2) -> doWkn (doWkn i view1) view2 = wkn i (thin2 . thin1) doWknHomo' : {0 i : Var (sx :< n)} -> (v : View i) -> (thin1 : sx `Thins` sy) -> (thin2 : sy `Thins` sz) -> doWkn' (view $ doWkn' v thin1) thin2 = doWkn' v (thin2 . thin1) doWknHomo i view1 (Id sz) = rewrite compLeftIdentity thin1 in cong (doWkn i) $ viewUnique view1 (view thin1) doWknHomo i view1 (Drop thin2 n) = rewrite compLeftDrop thin2 thin1 n in rewrite viewUnique (view $ drop (thin2 . thin1) n) (Drop (thin2 . thin1) n) in cong there $ doWknHomo i view1 (view thin2) doWknHomo i (Id _) (Keep thin2 n) = rewrite compRightIdentity $ keep thin2 n in rewrite viewUnique (view $ keep thin2 n) (Keep thin2 n) in Refl doWknHomo i (Drop thin1 n) (Keep thin2 n) = rewrite compRightDrop thin2 thin1 n in rewrite viewUnique (view $ drop (thin2 . thin1) n) (Drop (thin2 . thin1) n) in rewrite Var.viewUnique (view $ there {n} $ doWkn i $ view thin1) (There $ doWkn i $ view thin1) in cong there $ doWknHomo i (view thin1) (view thin2) doWknHomo i (Keep {prf = prf1} thin1 n) (Keep {prf = prf2} thin2 n) = rewrite compKeep thin2 thin1 n in rewrite viewUnique (view $ keep (thin2 . thin1) n) (Keep {prf = compPresNotId prf2 prf1} (thin2 . thin1) n) in doWknHomo' (view i) thin1 thin2 doWknHomo' Here thin1 thin2 = Refl doWknHomo' (There i) thin1 thin2 = rewrite viewUnique (view $ there {n} $ doWkn i $ view thin1) (There $ doWkn i $ view thin1) in cong there $ doWknHomo i (view thin1) (view thin2) export wknHomo : (i : Var sx) -> (thin1 : sx `Thins` sy) -> (thin2 : sy `Thins` sz) -> wkn (wkn i thin1) thin2 = wkn i (thin2 . thin1) wknHomo i thin1 thin2 = doWknHomo i (view thin1) (view thin2)