module Deontic.Core.Adjudicate
( Adjudicate(..)
, Judgment(..)
, verdict
, query
, SomeJudgment(..)
, someVerdict
, combineVerdicts
) where
import Data.Kind (Type)
import Data.Text (Text)
import GHC.TypeLits (TypeError, ErrorMessage(..))
import Deontic.Core.Types (ArticleRef, Facts)
import Data.List (foldl')
import Deontic.Core.Verdict (Verdict(..), verdictMeet)
import Deontic.Core.Layer (Resolvable)
data Judgment (layers :: [Type]) where
JBase :: Verdict -> ArticleRef -> Text
-> Judgment '[l]
JOverride :: Judgment prev -> Verdict -> ArticleRef -> Text
-> Judgment (l ': prev)
JDelegate :: Judgment prev
-> Judgment (l ': prev)
JCounterfactual :: Judgment prev -> SomeJudgment -> Verdict -> ArticleRef -> Text
-> Judgment (l ': prev)
verdict :: Judgment layers -> Verdict
verdict :: forall (layers :: [*]). Judgment layers -> Verdict
verdict (JBase Verdict
v ArticleRef
_ Text
_) = Verdict
v
verdict (JOverride Judgment prev
_ Verdict
v ArticleRef
_ Text
_) = Verdict
v
verdict (JDelegate Judgment prev
prev) = Judgment prev -> Verdict
forall (layers :: [*]). Judgment layers -> Verdict
verdict Judgment prev
prev
verdict (JCounterfactual Judgment prev
_ SomeJudgment
_ Verdict
v ArticleRef
_ Text
_) = Verdict
v
class Adjudicate act (layers :: [Type]) where
adjudicate :: act -> Facts act -> Judgment layers
instance TypeError
( 'Text "법의 흠결 (lacuna): no applicable rule for "
':<>: 'ShowType act
) => Adjudicate act '[] where
adjudicate :: act -> Facts act -> Judgment '[]
adjudicate = [Char] -> act -> Facts act -> Judgment '[]
forall a. HasCallStack => [Char] -> a
error [Char]
"unreachable"
query :: forall act. Adjudicate act (Resolvable act) => act -> Facts act -> Judgment (Resolvable act)
query :: forall act.
Adjudicate act (Resolvable act) =>
act -> Facts act -> Judgment (Resolvable act)
query act
act Facts act
facts = act -> Facts act -> Judgment (Resolvable act)
forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate act
act Facts act
facts
data SomeJudgment where
SomeJudgment :: Judgment layers -> SomeJudgment
someVerdict :: SomeJudgment -> Verdict
someVerdict :: SomeJudgment -> Verdict
someVerdict (SomeJudgment Judgment layers
j) = Judgment layers -> Verdict
forall (layers :: [*]). Judgment layers -> Verdict
verdict Judgment layers
j
combineVerdicts :: [SomeJudgment] -> Verdict
combineVerdicts :: [SomeJudgment] -> Verdict
combineVerdicts = (Verdict -> SomeJudgment -> Verdict)
-> Verdict -> [SomeJudgment] -> Verdict
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\Verdict
acc SomeJudgment
sj -> Verdict -> Verdict -> Verdict
verdictMeet Verdict
acc (SomeJudgment -> Verdict
someVerdict SomeJudgment
sj)) Verdict
Valid