2022-02-26 20:18:16 -05:00
|
|
|
module Quox.Equal
|
|
|
|
|
|
|
|
import public Quox.Syntax
|
|
|
|
import Quox.Error
|
|
|
|
|
|
|
|
%default total
|
|
|
|
|
|
|
|
|
|
|
|
public export
|
2022-04-06 14:31:38 -04:00
|
|
|
data Error
|
|
|
|
= Clash SomeTerm SomeTerm
|
2022-02-26 20:18:16 -05:00
|
|
|
| ClashU Universe Universe
|
|
|
|
| ClashQ Qty Qty
|
|
|
|
|
|
|
|
private %inline
|
|
|
|
clashT' : Term d n -> Term d n -> Error
|
|
|
|
clashT' = Clash `on` some2
|
|
|
|
|
|
|
|
private %inline
|
|
|
|
clashE' : Elim d n -> Elim d n -> Error
|
|
|
|
clashE' = clashT' `on` E
|
|
|
|
|
|
|
|
parameters {auto _ : MonadThrow Error m}
|
|
|
|
private %inline
|
|
|
|
clashT : Term d n -> Term d n -> m a
|
|
|
|
clashT = throw .: clashT'
|
|
|
|
|
|
|
|
private %inline
|
|
|
|
clashE : Elim d n -> Elim d n -> m a
|
|
|
|
clashE = clashT `on` E
|
|
|
|
|
|
|
|
private %inline
|
|
|
|
eq : Eq a => (a -> a -> Error) -> a -> a -> m ()
|
|
|
|
eq err a b = unless (a == b) $ throw $ err a b
|
|
|
|
|
|
|
|
mutual
|
|
|
|
private covering
|
2022-04-06 14:31:38 -04:00
|
|
|
equalTN' : (s, t : Term 0 n) ->
|
2022-02-26 20:18:16 -05:00
|
|
|
(0 _ : NotRedexT s) -> (0 _ : NotRedexT t) -> m ()
|
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
equalTN' (TYPE k) (TYPE l) _ _ =
|
2022-02-26 20:18:16 -05:00
|
|
|
eq ClashU k l
|
2022-04-06 14:31:38 -04:00
|
|
|
equalTN' s@(TYPE _) t _ _ = clashT s t
|
2022-02-26 20:18:16 -05:00
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
equalTN' (Pi qtm1 qty1 _ arg1 res1) (Pi qtm2 qty2 _ arg2 res2) _ _ = do
|
2022-02-26 20:18:16 -05:00
|
|
|
eq ClashQ qtm1 qtm2
|
|
|
|
eq ClashQ qty1 qty2
|
2022-04-06 14:31:38 -04:00
|
|
|
equalT0 arg1 arg2
|
|
|
|
equalT0 res1 res2
|
|
|
|
equalTN' s@(Pi {}) t _ _ = clashT s t
|
2022-02-26 20:18:16 -05:00
|
|
|
|
|
|
|
-- [todo] eta
|
2022-04-06 14:31:38 -04:00
|
|
|
equalTN' (Lam _ body1) (Lam _ body2) _ _ =
|
|
|
|
equalT0 body1 body2
|
|
|
|
equalTN' s@(Lam {}) t _ _ = clashT s t
|
2022-02-26 20:18:16 -05:00
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
equalTN' (E e) (E f) ps pt = equalE0 e f
|
|
|
|
equalTN' s@(E _) t _ _ = clashT s t
|
2022-02-26 20:18:16 -05:00
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
equalTN' (CloT {}) _ ps _ = void $ ps IsCloT
|
|
|
|
equalTN' (DCloT {}) _ ps _ = void $ ps IsDCloT
|
2022-02-26 20:18:16 -05:00
|
|
|
|
|
|
|
private covering
|
2022-04-06 14:31:38 -04:00
|
|
|
equalEN' : (e, f : Elim 0 n) ->
|
2022-02-26 20:18:16 -05:00
|
|
|
(0 _ : NotRedexE e) -> (0 _ : NotRedexE f) -> m ()
|
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
equalEN' (F x) (F y) _ _ = do
|
2022-02-26 20:18:16 -05:00
|
|
|
eq (clashE' `on` F {d = 0, n = 0}) x y
|
2022-04-06 14:31:38 -04:00
|
|
|
equalEN' e@(F _) f _ _ = clashE e f
|
2022-02-26 20:18:16 -05:00
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
equalEN' (B i) (B j) _ _ = do
|
2022-02-26 20:18:16 -05:00
|
|
|
eq (clashE' `on` B {d = 0}) i j
|
2022-04-06 14:31:38 -04:00
|
|
|
equalEN' e@(B _) f _ _ = clashE e f
|
2022-02-26 20:18:16 -05:00
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
equalEN' (fun1 :@ arg1) (fun2 :@ arg2) _ _ = do
|
|
|
|
equalE0 fun1 fun2
|
|
|
|
equalT0 arg1 arg2
|
|
|
|
equalEN' e@(_ :@ _) f _ _ = clashE e f
|
2022-02-26 20:18:16 -05:00
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
equalEN' (tm1 :# ty1) (tm2 :# ty2) _ _ = do
|
|
|
|
equalT0 tm1 tm2
|
|
|
|
equalT0 ty1 ty2
|
|
|
|
equalEN' e@(_ :# _) f _ _ = clashE e f
|
2022-02-26 20:18:16 -05:00
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
equalEN' (CloE {}) _ pe _ = void $ pe IsCloE
|
|
|
|
equalEN' (DCloE {}) _ pe _ = void $ pe IsDCloE
|
2022-02-26 20:18:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
private covering %inline
|
2022-04-06 14:31:38 -04:00
|
|
|
equalTN : NonRedexTerm 0 n -> NonRedexTerm 0 n -> m ()
|
|
|
|
equalTN s t = equalTN' s.fst t.fst s.snd t.snd
|
2022-02-26 20:18:16 -05:00
|
|
|
|
|
|
|
private covering %inline
|
2022-04-06 14:31:38 -04:00
|
|
|
equalEN : NonRedexElim 0 n -> NonRedexElim 0 n -> m ()
|
|
|
|
equalEN e f = equalEN' e.fst f.fst e.snd f.snd
|
2022-02-26 20:18:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
export covering %inline
|
2022-04-06 14:31:38 -04:00
|
|
|
equalT : DimEq d -> Term d n -> Term d n -> m ()
|
|
|
|
equalT eqs s t =
|
|
|
|
for_ (splits eqs) $ \th => (s /// th) `equalT0` (t /// th)
|
2022-02-26 20:18:16 -05:00
|
|
|
|
|
|
|
export covering %inline
|
2022-04-06 14:31:38 -04:00
|
|
|
equalE : DimEq d -> Elim d n -> Elim d n -> m ()
|
|
|
|
equalE eqs e f =
|
|
|
|
for_ (splits eqs) $ \th => (e /// th) `equalE0` (f /// th)
|
2022-02-26 20:18:16 -05:00
|
|
|
|
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
export covering %inline
|
|
|
|
equalT0 : Term 0 n -> Term 0 n -> m ()
|
|
|
|
equalT0 s t = whnfT s `equalTN` whnfT t
|
2022-02-26 20:18:16 -05:00
|
|
|
|
2022-04-06 14:31:38 -04:00
|
|
|
export covering %inline
|
|
|
|
equalE0 : Elim 0 n -> Elim 0 n -> m ()
|
|
|
|
equalE0 e f = whnfE e `equalEN` whnfE f
|