Homework/HomeworkEleven.idr

43 lines
1.1 KiB
Idris

module HomeworkEleven
%default total
data Move = Up | Rgt | Seq Move Move | Rev Move
Vec : Type
Vec = (Int, Int)
add : Vec -> Vec -> Vec
add (x1, y1) (x2, y2) = (x1+x2, y1+y2)
neg : Vec -> Vec
neg (x1, y1) = (negate x1, negate y1)
sem : Move -> Vec
sem Up = (0, 1)
sem Rgt = (1, 0)
sem (Seq s1 s2) = sem s1 `add` sem s2
sem (Rev s1) = neg $ sem s1
data Final : Move -> Vec -> Type where
FUp : Final Up (0, 1)
FRgt : Final Rgt (1, 0)
FSeq : Final s1 v1 -> Final s2 v2 -> Final (Seq s1 s2) (v1 `add` v2)
FRev : Final s v -> Final (Rev s) (neg v)
finalEx : Final ((Up `Seq` Up) `Seq` Rgt) (1, 2)
finalEx = (FUp `FSeq` FUp) `FSeq` FRgt
finalSem : Final s v -> sem s = v
finalSem FUp = Refl
finalSem FRgt = Refl
finalSem (FRev f) with (finalSem f) | Refl = Refl
finalSem (FSeq f1 f2) with (finalSem f1, finalSem f2) | (Refl, Refl) = Refl
semFinal : sem s = v -> Final s v
semFinal {s=Up} Refl = FUp
semFinal {s=Rgt} Refl = FRgt
semFinal {s=Rev s1} Refl with (sem s1) proof p1
| _ = FRev (semFinal (sym p1))
semFinal {s=Seq s1 s2} Refl with (sem s1, sem s2) proof p
| (_, _) = let Refl = p in FSeq (semFinal Refl) (semFinal Refl)