{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Rzk.TypeCheck.NbE (Conversion (..), nbeConvertible) where
import Control.Monad.Reader (asks)
import Data.Bifoldable (bifoldMap)
import Data.Bifunctor (bimap)
import Data.Monoid (All (..))
import Data.ZipMatchK (zipMatch2)
import Control.Monad.Foil (NameBinder)
import qualified Control.Monad.Foil as Foil
import Control.Monad.Free.Foil (AST (Node, Var),
ScopedAST (..))
import Control.Monad.Free.Foil.Annotated (AnnSig (..))
import Language.Rzk.Foil.Syntax
import Rzk.TypeCheck.Context
import Rzk.TypeCheck.Monad
data Val n
= VLam (Closure n)
| VNeutral (Neu n)
| VCon (TermSig (Closure n) (Val n))
| VAbort
data Neu n
= NRigid (Head n) [Elim n]
| NGlued (Foil.Name n) [Elim n] (Val n)
data Head n
= HVar (Foil.Name n)
| HFresh DeBruijnLevel
data Elim n
= EApp (Val n)
| EFirst
| ESecond
| EIdJ (Val n) (Val n) (Val n) (Val n) (Val n)
newtype DeBruijnLevel = DeBruijnLevel Int
deriving (DeBruijnLevel -> DeBruijnLevel -> Bool
(DeBruijnLevel -> DeBruijnLevel -> Bool)
-> (DeBruijnLevel -> DeBruijnLevel -> Bool) -> Eq DeBruijnLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DeBruijnLevel -> DeBruijnLevel -> Bool
== :: DeBruijnLevel -> DeBruijnLevel -> Bool
$c/= :: DeBruijnLevel -> DeBruijnLevel -> Bool
/= :: DeBruijnLevel -> DeBruijnLevel -> Bool
Eq)
nextLevel :: DeBruijnLevel -> DeBruijnLevel
nextLevel :: DeBruijnLevel -> DeBruijnLevel
nextLevel (DeBruijnLevel Int
i) = Int -> DeBruijnLevel
DeBruijnLevel (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
elimNeu :: Elim n -> (Val n -> Val n) -> Neu n -> Neu n
elimNeu :: forall (n :: S). Elim n -> (Val n -> Val n) -> Neu n -> Neu n
elimNeu Elim n
e Val n -> Val n
onUnfolding = \case
NRigid Head n
h [Elim n]
es -> Head n -> [Elim n] -> Neu n
forall (n :: S). Head n -> [Elim n] -> Neu n
NRigid Head n
h (Elim n
e Elim n -> [Elim n] -> [Elim n]
forall a. a -> [a] -> [a]
: [Elim n]
es)
NGlued Name n
x [Elim n]
es Val n
u -> Name n -> [Elim n] -> Val n -> Neu n
forall (n :: S). Name n -> [Elim n] -> Val n -> Neu n
NGlued Name n
x (Elim n
e Elim n -> [Elim n] -> [Elim n]
forall a. a -> [a] -> [a]
: [Elim n]
es) (Val n -> Val n
onUnfolding Val n
u)
headOf :: Neu n -> Head n
headOf :: forall (n :: S). Neu n -> Head n
headOf (NRigid Head n
h [Elim n]
_) = Head n
h
headOf (NGlued Name n
x [Elim n]
_ Val n
_) = Name n -> Head n
forall (n :: S). Name n -> Head n
HVar Name n
x
elimsOf :: Neu n -> [Elim n]
elimsOf :: forall (n :: S). Neu n -> [Elim n]
elimsOf (NRigid Head n
_ [Elim n]
es) = [Elim n]
es
elimsOf (NGlued Name n
_ [Elim n]
es Val n
_) = [Elim n]
es
data Closure n where
Closure :: Env i n -> NameBinder i l -> TermT l -> Closure n
type Env i n = Foil.Substitution Val i n
instance Foil.InjectName Val where
injectName :: forall (n :: S). Name n -> Val n
injectName Name n
x = Neu n -> Val n
forall (n :: S). Neu n -> Val n
VNeutral (Head n -> [Elim n] -> Neu n
forall (n :: S). Head n -> [Elim n] -> Neu n
NRigid (Name n -> Head n
forall (n :: S). Name n -> Head n
HVar Name n
x) [])
eval :: forall i n. Context n -> Env i n -> TermT i -> Val n
eval :: forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env = \case
Var Name i
x -> case Env i n -> Name i -> Val n
forall (e :: S -> *) (i :: S) (o :: S).
InjectName e =>
Substitution e i o -> Name i -> e o
Foil.lookupSubst Env i n
env Name i
x of
v :: Val n
v@(VNeutral (NRigid (HVar Name n
x') [])) ->
case VarInfo n -> Maybe (TermT n)
forall (n :: S). VarInfo n -> Maybe (TermT n)
varValue (Name n -> Context n -> VarInfo n
forall (n :: S). Name n -> Context n -> VarInfo n
lookupVarInfo Name n
x' Context n
ctx) of
Maybe (TermT n)
Nothing -> Val n
v
Just TermT n
body -> Neu n -> Val n
forall (n :: S). Neu n -> Val n
VNeutral (Name n -> [Elim n] -> Val n -> Neu n
forall (n :: S). Name n -> [Elim n] -> Val n -> Neu n
NGlued Name n
x' [] (Context n -> Env n n -> TermT n -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env n n
forall (e :: S -> *) (i :: S). InjectName e => Substitution e i i
Foil.identitySubst TermT n
body))
Val n
v -> Val n
v
AppT TypeInfo (TermT i)
_ty TermT i
f TermT i
x -> Context n -> Val n -> Val n -> Val n
forall (n :: S). Context n -> Val n -> Val n -> Val n
applyVal Context n
ctx (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
f) (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
x)
LambdaT TypeInfo (TermT i)
_ty Binder
_orig Maybe
(LambdaParam
(ScopedAST NameBinder (AnnSig TypeInfo TermSig) i) (TermT i))
_mparam (ScopedAST NameBinder i l
binder AST NameBinder (AnnSig TypeInfo TermSig) l
body) ->
Closure n -> Val n
forall (n :: S). Closure n -> Val n
VLam (Env i n
-> NameBinder i l
-> AST NameBinder (AnnSig TypeInfo TermSig) l
-> Closure n
forall (i :: S) (n :: S) (l :: S).
Env i n -> NameBinder i l -> TermT l -> Closure n
Closure Env i n
env NameBinder i l
binder AST NameBinder (AnnSig TypeInfo TermSig) l
body)
LetT TypeInfo (TermT i)
_ty Binder
_orig Maybe (TermT i)
_mparam TermT i
val (ScopedAST NameBinder i l
binder AST NameBinder (AnnSig TypeInfo TermSig) l
body) ->
Context n
-> Env l n -> AST NameBinder (AnnSig TypeInfo TermSig) l -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx (Env i n -> NameBinder i l -> Val n -> Env l n
forall (e :: S -> *) (i :: S) (o :: S) (i' :: S).
Substitution e i o -> NameBinder i i' -> e o -> Substitution e i' o
Foil.addSubst Env i n
env NameBinder i l
binder (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
val)) AST NameBinder (AnnSig TypeInfo TermSig) l
body
FirstT TypeInfo (TermT i)
_ty TermT i
t -> Proj -> Val n -> Val n
forall (n :: S). Proj -> Val n -> Val n
projVal Proj
ProjFirst (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
t)
SecondT TypeInfo (TermT i)
_ty TermT i
t -> Proj -> Val n -> Val n
forall (n :: S). Proj -> Val n -> Val n
projVal Proj
ProjSecond (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
t)
TypeAscT TypeInfo (TermT i)
_ty TermT i
term TermT i
_ty' -> Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
term
IdJT TypeInfo (TermT i)
_ty TermT i
tA TermT i
a TermT i
tC TermT i
d TermT i
x TermT i
p ->
let vd :: Val n
vd = Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
d
e :: Elim n
e = Val n -> Val n -> Val n -> Val n -> Val n -> Elim n
forall (n :: S).
Val n -> Val n -> Val n -> Val n -> Val n -> Elim n
EIdJ (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
tA) (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
a) (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
tC)
Val n
vd (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
x)
elim :: Val n -> Val n
elim = \case
VCon ReflF{} -> Val n
vd
VNeutral Neu n
neu -> Neu n -> Val n
forall (n :: S). Neu n -> Val n
VNeutral (Elim n -> (Val n -> Val n) -> Neu n -> Neu n
forall (n :: S). Elim n -> (Val n -> Val n) -> Neu n -> Neu n
elimNeu Elim n
e Val n -> Val n
elim Neu n
neu)
Val n
_ -> Val n
forall (n :: S). Val n
VAbort
in Val n -> Val n
elim (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env TermT i
p)
HoleT{} -> Val n
forall (n :: S). Val n
VAbort
RecOrT{} -> Val n
forall (n :: S). Val n
VAbort
TypeModalT{} -> Val n
forall (n :: S). Val n
VAbort
ModAppT{} -> Val n
forall (n :: S). Val n
VAbort
ModExtractT{} -> Val n
forall (n :: S). Val n
VAbort
LetModT{} -> Val n
forall (n :: S). Val n
VAbort
Node (AnnSig TypeInfo (TermT i)
_info TermSig
(ScopedAST NameBinder (AnnSig TypeInfo TermSig) i) (TermT i)
sig) ->
TermSig (Closure n) (Val n) -> Val n
forall (n :: S). TermSig (Closure n) (Val n) -> Val n
VCon ((ScopedAST NameBinder (AnnSig TypeInfo TermSig) i -> Closure n)
-> (TermT i -> Val n)
-> TermSig
(ScopedAST NameBinder (AnnSig TypeInfo TermSig) i) (TermT i)
-> TermSig (Closure n) (Val n)
forall a b c d. (a -> b) -> (c -> d) -> TermSig a c -> TermSig b d
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap (\(ScopedAST NameBinder i l
binder AST NameBinder (AnnSig TypeInfo TermSig) l
body) -> Env i n
-> NameBinder i l
-> AST NameBinder (AnnSig TypeInfo TermSig) l
-> Closure n
forall (i :: S) (n :: S) (l :: S).
Env i n -> NameBinder i l -> TermT l -> Closure n
Closure Env i n
env NameBinder i l
binder AST NameBinder (AnnSig TypeInfo TermSig) l
body) (Context n -> Env i n -> TermT i -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env i n
env) TermSig
(ScopedAST NameBinder (AnnSig TypeInfo TermSig) i) (TermT i)
sig)
applyVal :: Context n -> Val n -> Val n -> Val n
applyVal :: forall (n :: S). Context n -> Val n -> Val n -> Val n
applyVal Context n
ctx Val n
f Val n
v = case Val n
f of
VLam Closure n
closure -> Context n -> Closure n -> Val n -> Val n
forall (n :: S). Context n -> Closure n -> Val n -> Val n
applyClosure Context n
ctx Closure n
closure Val n
v
VNeutral Neu n
neu -> Neu n -> Val n
forall (n :: S). Neu n -> Val n
VNeutral (Elim n -> (Val n -> Val n) -> Neu n -> Neu n
forall (n :: S). Elim n -> (Val n -> Val n) -> Neu n -> Neu n
elimNeu (Val n -> Elim n
forall (n :: S). Val n -> Elim n
EApp Val n
v) (\Val n
u -> Context n -> Val n -> Val n -> Val n
forall (n :: S). Context n -> Val n -> Val n -> Val n
applyVal Context n
ctx Val n
u Val n
v) Neu n
neu)
Val n
_ -> Val n
forall (n :: S). Val n
VAbort
applyClosure :: Context n -> Closure n -> Val n -> Val n
applyClosure :: forall (n :: S). Context n -> Closure n -> Val n -> Val n
applyClosure Context n
ctx (Closure Env i n
env NameBinder i l
binder TermT l
body) Val n
v =
Context n -> Env l n -> TermT l -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx (Env i n -> NameBinder i l -> Val n -> Env l n
forall (e :: S -> *) (i :: S) (o :: S) (i' :: S).
Substitution e i o -> NameBinder i i' -> e o -> Substitution e i' o
Foil.addSubst Env i n
env NameBinder i l
binder Val n
v) TermT l
body
data Proj = ProjFirst | ProjSecond
projVal :: Proj -> Val n -> Val n
projVal :: forall (n :: S). Proj -> Val n -> Val n
projVal Proj
proj = Val n -> Val n
go
where
go :: Val n -> Val n
go = \case
VCon (PairF Val n
l Val n
r) -> case Proj
proj of
Proj
ProjFirst -> Val n
l
Proj
ProjSecond -> Val n
r
VNeutral Neu n
neu -> Neu n -> Val n
forall (n :: S). Neu n -> Val n
VNeutral (Elim n -> (Val n -> Val n) -> Neu n -> Neu n
forall (n :: S). Elim n -> (Val n -> Val n) -> Neu n -> Neu n
elimNeu Elim n
e Val n -> Val n
go Neu n
neu)
Val n
_ -> Val n
forall (n :: S). Val n
VAbort
e :: Elim n
e = case Proj
proj of
Proj
ProjFirst -> Elim n
forall (n :: S). Elim n
EFirst
Proj
ProjSecond -> Elim n
forall (n :: S). Elim n
ESecond
conv :: Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv :: forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl Val n
l Val n
r
| Val n -> Val n -> Bool
align Val n
l Val n
r = Bool
True
| Bool
otherwise = case (Val n -> Val n
forall {n :: S}. Val n -> Val n
forceVal Val n
l, Val n -> Val n
forall {n :: S}. Val n -> Val n
forceVal Val n
r) of
(Val n
VAbort, Val n
_) -> Bool
False
(Val n
_, Val n
VAbort) -> Bool
False
(VLam Closure n
c1, VLam Closure n
c2) ->
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx (DeBruijnLevel -> DeBruijnLevel
nextLevel DeBruijnLevel
lvl) (Context n -> Closure n -> Val n -> Val n
forall (n :: S). Context n -> Closure n -> Val n -> Val n
applyClosure Context n
ctx Closure n
c1 (DeBruijnLevel -> Val n
forall {n :: S}. DeBruijnLevel -> Val n
freshV DeBruijnLevel
lvl)) (Context n -> Closure n -> Val n -> Val n
forall (n :: S). Context n -> Closure n -> Val n -> Val n
applyClosure Context n
ctx Closure n
c2 (DeBruijnLevel -> Val n
forall {n :: S}. DeBruijnLevel -> Val n
freshV DeBruijnLevel
lvl))
(VLam Closure n
c1, Val n
v2) ->
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx (DeBruijnLevel -> DeBruijnLevel
nextLevel DeBruijnLevel
lvl) (Context n -> Closure n -> Val n -> Val n
forall (n :: S). Context n -> Closure n -> Val n -> Val n
applyClosure Context n
ctx Closure n
c1 (DeBruijnLevel -> Val n
forall {n :: S}. DeBruijnLevel -> Val n
freshV DeBruijnLevel
lvl)) (Context n -> Val n -> Val n -> Val n
forall (n :: S). Context n -> Val n -> Val n -> Val n
applyVal Context n
ctx Val n
v2 (DeBruijnLevel -> Val n
forall {n :: S}. DeBruijnLevel -> Val n
freshV DeBruijnLevel
lvl))
(Val n
v1, VLam Closure n
c2) ->
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx (DeBruijnLevel -> DeBruijnLevel
nextLevel DeBruijnLevel
lvl) (Context n -> Val n -> Val n -> Val n
forall (n :: S). Context n -> Val n -> Val n -> Val n
applyVal Context n
ctx Val n
v1 (DeBruijnLevel -> Val n
forall {n :: S}. DeBruijnLevel -> Val n
freshV DeBruijnLevel
lvl)) (Context n -> Closure n -> Val n -> Val n
forall (n :: S). Context n -> Closure n -> Val n -> Val n
applyClosure Context n
ctx Closure n
c2 (DeBruijnLevel -> Val n
forall {n :: S}. DeBruijnLevel -> Val n
freshV DeBruijnLevel
lvl))
(VCon (PairF Val n
a Val n
b), n :: Val n
n@(VNeutral Neu n
_)) ->
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl Val n
a (Proj -> Val n -> Val n
forall (n :: S). Proj -> Val n -> Val n
projVal Proj
ProjFirst Val n
n) Bool -> Bool -> Bool
&& Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl Val n
b (Proj -> Val n -> Val n
forall (n :: S). Proj -> Val n -> Val n
projVal Proj
ProjSecond Val n
n)
(n :: Val n
n@(VNeutral Neu n
_), VCon (PairF Val n
a Val n
b)) ->
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl (Proj -> Val n -> Val n
forall (n :: S). Proj -> Val n -> Val n
projVal Proj
ProjFirst Val n
n) Val n
a Bool -> Bool -> Bool
&& Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl (Proj -> Val n -> Val n
forall (n :: S). Proj -> Val n -> Val n
projVal Proj
ProjSecond Val n
n) Val n
b
(VCon TermSig (Closure n) (Val n)
s1, VCon TermSig (Closure n) (Val n)
s2) -> case TermSig (Closure n) (Val n)
-> TermSig (Closure n) (Val n)
-> Maybe (TermSig (Closure n, Closure n) (Val n, Val n))
forall (f :: * -> * -> *) a b a' b'.
(Bitraversable f, ZipMatchK f) =>
f a b -> f a' b' -> Maybe (f (a, a') (b, b'))
zipMatch2 TermSig (Closure n) (Val n)
s1 TermSig (Closure n) (Val n)
s2 of
Maybe (TermSig (Closure n, Closure n) (Val n, Val n))
Nothing -> Bool
False
Just TermSig (Closure n, Closure n) (Val n, Val n)
s -> All -> Bool
getAll (((Closure n, Closure n) -> All)
-> ((Val n, Val n) -> All)
-> TermSig (Closure n, Closure n) (Val n, Val n)
-> All
forall m a b. Monoid m => (a -> m) -> (b -> m) -> TermSig a b -> m
forall (p :: * -> * -> *) m a b.
(Bifoldable p, Monoid m) =>
(a -> m) -> (b -> m) -> p a b -> m
bifoldMap
(Bool -> All
All (Bool -> All)
-> ((Closure n, Closure n) -> Bool)
-> (Closure n, Closure n)
-> All
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Closure n -> Closure n -> Bool) -> (Closure n, Closure n) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Context n -> DeBruijnLevel -> Closure n -> Closure n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Closure n -> Closure n -> Bool
convClosure Context n
ctx DeBruijnLevel
lvl))
(Bool -> All
All (Bool -> All) -> ((Val n, Val n) -> Bool) -> (Val n, Val n) -> All
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Val n -> Val n -> Bool) -> (Val n, Val n) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl))
TermSig (Closure n, Closure n) (Val n, Val n)
s)
(VNeutral Neu n
n1, VNeutral Neu n
n2) -> Context n -> DeBruijnLevel -> Neu n -> Neu n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Neu n -> Neu n -> Bool
convNeu Context n
ctx DeBruijnLevel
lvl Neu n
n1 Neu n
n2
(Val n, Val n)
_ -> Bool
False
where
freshV :: DeBruijnLevel -> Val n
freshV DeBruijnLevel
k = Neu n -> Val n
forall (n :: S). Neu n -> Val n
VNeutral (Head n -> [Elim n] -> Neu n
forall (n :: S). Head n -> [Elim n] -> Neu n
NRigid (DeBruijnLevel -> Head n
forall (n :: S). DeBruijnLevel -> Head n
HFresh DeBruijnLevel
k) [])
aligned :: Val n -> Val n -> Bool
aligned (VNeutral n1 :: Neu n
n1@NGlued{}) (VNeutral Neu n
n2) = Context n -> DeBruijnLevel -> Neu n -> Neu n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Neu n -> Neu n -> Bool
convNeu Context n
ctx DeBruijnLevel
lvl Neu n
n1 Neu n
n2
aligned Val n
_ Val n
_ = Bool
False
unfolded :: Val n -> Maybe (Val n)
unfolded (VNeutral (NGlued Name n
_ [Elim n]
_ Val n
u)) = Val n -> Maybe (Val n)
forall a. a -> Maybe a
Just Val n
u
unfolded Val n
_ = Maybe (Val n)
forall a. Maybe a
Nothing
align :: Val n -> Val n -> Bool
align Val n
a Val n
b = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or
[ Val n -> Val n -> Bool
aligned Val n
a' Val n
b'
| Int
k <- [Int
0 .. Int
maxAlignOffset]
, (Int
i, Val n
a') <- [Int] -> [Val n] -> [(Int, Val n)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 :: Int ..] (Val n -> [Val n]
forall {n :: S}. Val n -> [Val n]
chainOf Val n
a)
, (Int
j, Val n
b') <- [Int] -> [Val n] -> [(Int, Val n)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 :: Int ..] (Val n -> [Val n]
forall {n :: S}. Val n -> [Val n]
chainOf Val n
b)
, Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
i Int
j Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
k ]
chainOf :: Val n -> [Val n]
chainOf Val n
v = Int -> [Val n] -> [Val n]
forall a. Int -> [a] -> [a]
take (Int
maxAlignOffset Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Val n
v Val n -> [Val n] -> [Val n]
forall a. a -> [a] -> [a]
: [Val n] -> (Val n -> [Val n]) -> Maybe (Val n) -> [Val n]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] Val n -> [Val n]
chainOf (Val n -> Maybe (Val n)
forall {n :: S}. Val n -> Maybe (Val n)
unfolded Val n
v))
forceVal :: Val n -> Val n
forceVal Val n
v = Val n -> (Val n -> Val n) -> Maybe (Val n) -> Val n
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Val n
v Val n -> Val n
forceVal (Val n -> Maybe (Val n)
forall {n :: S}. Val n -> Maybe (Val n)
unfolded Val n
v)
maxAlignOffset :: Int
maxAlignOffset :: Int
maxAlignOffset = Int
4
convClosure :: Context n -> DeBruijnLevel -> Closure n -> Closure n -> Bool
convClosure :: forall (n :: S).
Context n -> DeBruijnLevel -> Closure n -> Closure n -> Bool
convClosure Context n
ctx DeBruijnLevel
lvl Closure n
c1 Closure n
c2 =
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx (DeBruijnLevel -> DeBruijnLevel
nextLevel DeBruijnLevel
lvl) (Context n -> Closure n -> Val n -> Val n
forall (n :: S). Context n -> Closure n -> Val n -> Val n
applyClosure Context n
ctx Closure n
c1 Val n
fresh) (Context n -> Closure n -> Val n -> Val n
forall (n :: S). Context n -> Closure n -> Val n -> Val n
applyClosure Context n
ctx Closure n
c2 Val n
fresh)
where
fresh :: Val n
fresh = Neu n -> Val n
forall (n :: S). Neu n -> Val n
VNeutral (Head n -> [Elim n] -> Neu n
forall (n :: S). Head n -> [Elim n] -> Neu n
NRigid (DeBruijnLevel -> Head n
forall (n :: S). DeBruijnLevel -> Head n
HFresh DeBruijnLevel
lvl) [])
convNeu :: Context n -> DeBruijnLevel -> Neu n -> Neu n -> Bool
convNeu :: forall (n :: S).
Context n -> DeBruijnLevel -> Neu n -> Neu n -> Bool
convNeu Context n
ctx DeBruijnLevel
lvl Neu n
n1 Neu n
n2 =
Head n -> Head n -> Bool
forall {l :: S} {l :: S}. Head l -> Head l -> Bool
convHead (Neu n -> Head n
forall (n :: S). Neu n -> Head n
headOf Neu n
n1) (Neu n -> Head n
forall (n :: S). Neu n -> Head n
headOf Neu n
n2) Bool -> Bool -> Bool
&& [Elim n] -> [Elim n] -> Bool
convElims (Neu n -> [Elim n]
forall (n :: S). Neu n -> [Elim n]
elimsOf Neu n
n1) (Neu n -> [Elim n]
forall (n :: S). Neu n -> [Elim n]
elimsOf Neu n
n2)
where
convHead :: Head l -> Head l -> Bool
convHead (HVar Name l
x) (HVar Name l
y) = Name l -> Int
forall (l :: S). Name l -> Int
Foil.nameId Name l
x Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Name l -> Int
forall (l :: S). Name l -> Int
Foil.nameId Name l
y
convHead (HFresh DeBruijnLevel
i) (HFresh DeBruijnLevel
j) = DeBruijnLevel
i DeBruijnLevel -> DeBruijnLevel -> Bool
forall a. Eq a => a -> a -> Bool
== DeBruijnLevel
j
convHead Head l
_ Head l
_ = Bool
False
convElims :: [Elim n] -> [Elim n] -> Bool
convElims [] [] = Bool
True
convElims (Elim n
e:[Elim n]
es) (Elim n
e':[Elim n]
es') = [Elim n] -> [Elim n] -> Bool
convElims [Elim n]
es [Elim n]
es' Bool -> Bool -> Bool
&& Elim n -> Elim n -> Bool
convElim Elim n
e Elim n
e'
convElims [Elim n]
_ [Elim n]
_ = Bool
False
convElim :: Elim n -> Elim n -> Bool
convElim (EApp Val n
v) (EApp Val n
v') = Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl Val n
v Val n
v'
convElim Elim n
EFirst Elim n
EFirst = Bool
True
convElim Elim n
ESecond Elim n
ESecond = Bool
True
convElim (EIdJ Val n
tA Val n
a Val n
tC Val n
d Val n
x) (EIdJ Val n
tA' Val n
a' Val n
tC' Val n
d' Val n
x') =
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl Val n
tA Val n
tA' Bool -> Bool -> Bool
&& Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl Val n
a Val n
a' Bool -> Bool -> Bool
&& Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl Val n
tC Val n
tC'
Bool -> Bool -> Bool
&& Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl Val n
d Val n
d' Bool -> Bool -> Bool
&& Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx DeBruijnLevel
lvl Val n
x Val n
x'
convElim Elim n
_ Elim n
_ = Bool
False
data Conversion
= Convertible
| DontKnow
deriving (Conversion -> Conversion -> Bool
(Conversion -> Conversion -> Bool)
-> (Conversion -> Conversion -> Bool) -> Eq Conversion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Conversion -> Conversion -> Bool
== :: Conversion -> Conversion -> Bool
$c/= :: Conversion -> Conversion -> Bool
/= :: Conversion -> Conversion -> Bool
Eq, Int -> Conversion -> ShowS
[Conversion] -> ShowS
Conversion -> String
(Int -> Conversion -> ShowS)
-> (Conversion -> String)
-> ([Conversion] -> ShowS)
-> Show Conversion
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Conversion -> ShowS
showsPrec :: Int -> Conversion -> ShowS
$cshow :: Conversion -> String
show :: Conversion -> String
$cshowList :: [Conversion] -> ShowS
showList :: [Conversion] -> ShowS
Show)
nbeConvertible :: TermT n -> TermT n -> TypeCheck n Conversion
nbeConvertible :: forall (n :: S). TermT n -> TermT n -> TypeCheck n Conversion
nbeConvertible TermT n
t1 TermT n
t2 = (Context n -> Conversion)
-> ReaderT
(Context n)
(ExceptT TypeErrorInScopedContext (State CheckLog))
Conversion
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks ((Context n -> Conversion)
-> ReaderT
(Context n)
(ExceptT TypeErrorInScopedContext (State CheckLog))
Conversion)
-> (Context n -> Conversion)
-> ReaderT
(Context n)
(ExceptT TypeErrorInScopedContext (State CheckLog))
Conversion
forall a b. (a -> b) -> a -> b
$ \Context n
ctx ->
if Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
forall (n :: S).
Context n -> DeBruijnLevel -> Val n -> Val n -> Bool
conv Context n
ctx (Int -> DeBruijnLevel
DeBruijnLevel Int
0) (Context n -> Env n n -> TermT n -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env n n
forall (e :: S -> *) (i :: S). InjectName e => Substitution e i i
Foil.identitySubst TermT n
t1) (Context n -> Env n n -> TermT n -> Val n
forall (i :: S) (n :: S). Context n -> Env i n -> TermT i -> Val n
eval Context n
ctx Env n n
forall (e :: S -> *) (i :: S). InjectName e => Substitution e i i
Foil.identitySubst TermT n
t2)
then Conversion
Convertible
else Conversion
DontKnow