quox/lib/Quox/OPE/Split.idr

38 lines
1.1 KiB
Idris

module Quox.OPE.Split
import Quox.OPE.Basics
import Quox.OPE.Length
import Quox.OPE.Sub
%default total
public export
record Split {a : Type} (xs, ys, zs : Scope a) (p : xs `Sub` ys ++ zs) where
constructor MkSplit
{0 leftSub, rightSub : Scope a}
leftThin : leftSub `Sub` ys
rightThin : rightSub `Sub` zs
0 eqScope : xs = leftSub ++ rightSub
0 eqThin : p ~=~ leftThin ++ rightThin
export
split : Length ys =>
(zs : Scope a) -> (p : xs `Sub` ys ++ zs) -> Split xs ys zs p
split [<] p = MkSplit p zero Refl (endRight p)
split (zs :< z) p @{ys} with (p.view @{S (lengthApp ys %search)})
split (zs :< z) (SubM (S (2 * n)) (Keep p) v0) | (KEEP v Refl) =
case split zs (sub v) of
MkSplit l r Refl t =>
MkSplit l (keep r) Refl $
rewrite viewIrrel v0 (KEEP v Refl) in
trans (cong keep {a = sub v} t) $
sym $ keepAppRight l r
split (zs :< z) (SubM (2 * n) (Drop p) v0) | (DROP v Refl) =
case split zs (sub v) of
MkSplit l r Refl t =>
MkSplit l (drop r) Refl $
rewrite viewIrrel v0 (DROP v Refl) in
trans (cong drop {a = sub v} t) $
sym $ dropAppRight l r