module Deontic.Civil.Acts () where

import qualified Data.Set as Set
import Deontic.Core.Types
import Deontic.Core.Verdict
import Deontic.Core.Layer
import Deontic.Core.Adjudicate
import Deontic.Civil.Types (JuristicAct(..), ShamAct(..), MistakeAct(..), FraudAct(..), CivilFact(..))

type instance Resolvable JuristicAct = '[SpecialRule, Proviso, Base]

-- 제107조(비진의 의사표시) — Base layer
instance Adjudicate JuristicAct '[Base] where
  adjudicate :: JuristicAct -> Facts JuristicAct -> Judgment '[Base]
adjudicate JuristicAct
_ Facts JuristicAct
facts
    | CivilFact
HiddenIntention CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts JuristicAct
facts =
        Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Valid
          (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
107 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1))
          Text
"의사표시는 표의자가 진의아님을 알고 한 것이라도 그 효력에 영향을 미치지 아니한다."
    | Bool
otherwise =
        Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Valid
          (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
0 Maybe Int
forall a. Maybe a
Nothing)
          Text
"법률행위의 일반적 유효 추정"

-- 제107조 ② — Proviso layer
instance Adjudicate JuristicAct rest
      => Adjudicate JuristicAct (Proviso ': rest) where
  adjudicate :: JuristicAct -> Facts JuristicAct -> Judgment (Proviso : rest)
adjudicate JuristicAct
act Facts JuristicAct
facts
    | CivilFact
HiddenIntention CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts JuristicAct
facts
      Bool -> Bool -> Bool
&& CivilFact
CounterpartyKnew CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts JuristicAct
facts =
        Judgment rest
-> Verdict -> ArticleRef -> Text -> Judgment (Proviso : rest)
forall (prev :: [*]) l.
Judgment prev
-> Verdict -> ArticleRef -> Text -> Judgment (l : prev)
JOverride (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest JuristicAct
act Facts JuristicAct
facts)
                  Verdict
Void
                  (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
107 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2))
                  Text
"상대방이 표의자의 진의아님을 알았거나 알 수 있었을 경우에는 무효로 한다."
    | Bool
otherwise =
        Judgment rest -> Judgment (Proviso : rest)
forall (prev :: [*]) l. Judgment prev -> Judgment (l : prev)
JDelegate (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest JuristicAct
act Facts JuristicAct
facts)

-- 제103조, 제104조 — SpecialRule layer (overrides everything)
instance Adjudicate JuristicAct rest
      => Adjudicate JuristicAct (SpecialRule ': rest) where
  adjudicate :: JuristicAct -> Facts JuristicAct -> Judgment (SpecialRule : rest)
adjudicate JuristicAct
act Facts JuristicAct
facts
    | CivilFact
ContraBonorsMores CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts JuristicAct
facts =
        Judgment rest
-> Verdict -> ArticleRef -> Text -> Judgment (SpecialRule : rest)
forall (prev :: [*]) l.
Judgment prev
-> Verdict -> ArticleRef -> Text -> Judgment (l : prev)
JOverride (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest JuristicAct
act Facts JuristicAct
facts)
                  Verdict
Void
                  (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
103 Maybe Int
forall a. Maybe a
Nothing)
                  Text
"선량한 풍속 기타 사회질서에 위반한 사항을 내용으로 하는 법률행위는 무효로 한다."
    | CivilFact
ExploitativeAct CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts JuristicAct
facts =
        Judgment rest
-> Verdict -> ArticleRef -> Text -> Judgment (SpecialRule : rest)
forall (prev :: [*]) l.
Judgment prev
-> Verdict -> ArticleRef -> Text -> Judgment (l : prev)
JOverride (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest JuristicAct
act Facts JuristicAct
facts)
                  Verdict
Void
                  (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
104 Maybe Int
forall a. Maybe a
Nothing)
                  Text
"당사자의 궁박, 경솔 또는 무경험으로 인하여 현저하게 공정을 잃은 법률행위는 무효로 한다."
    | Bool
otherwise =
        Judgment rest -> Judgment (SpecialRule : rest)
forall (prev :: [*]) l. Judgment prev -> Judgment (l : prev)
JDelegate (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest JuristicAct
act Facts JuristicAct
facts)

-- ═══════════════════════════════════════════════
-- 제108조 — 통정허위표시
-- ═══════════════════════════════════════════════

type instance Resolvable ShamAct = '[Proviso, Base]

-- 제108조 ① "상대방과 통정한 허위의 의사표시는 무효로 한다."
instance Adjudicate ShamAct '[Base] where
  adjudicate :: ShamAct -> Facts ShamAct -> Judgment '[Base]
adjudicate ShamAct
_ Facts ShamAct
_ =
    Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Void
      (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
108 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1))
      Text
"상대방과 통정한 허위의 의사표시는 무효로 한다."

-- 제108조 ② "전항의 의사표시의 무효는 선의의 제삼자에게 대항하지 못한다."
instance Adjudicate ShamAct rest
      => Adjudicate ShamAct (Proviso ': rest) where
  adjudicate :: ShamAct -> Facts ShamAct -> Judgment (Proviso : rest)
adjudicate ShamAct
act Facts ShamAct
facts
    | CivilFact
BonaFideThirdParty CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts ShamAct
facts =
        Judgment rest
-> Verdict -> ArticleRef -> Text -> Judgment (Proviso : rest)
forall (prev :: [*]) l.
Judgment prev
-> Verdict -> ArticleRef -> Text -> Judgment (l : prev)
JOverride (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest ShamAct
act Facts ShamAct
facts)
                  Verdict
Valid
                  (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
108 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2))
                  Text
"전항의 의사표시의 무효는 선의의 제삼자에게 대항하지 못한다."
    | Bool
otherwise =
        Judgment rest -> Judgment (Proviso : rest)
forall (prev :: [*]) l. Judgment prev -> Judgment (l : prev)
JDelegate (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest ShamAct
act Facts ShamAct
facts)

-- ═══════════════════════════════════════════════
-- 제109조 — 착오로 인한 의사표시
-- ═══════════════════════════════════════════════

type instance Resolvable MistakeAct = '[Proviso, Base]

-- 제109조 ① 본문
-- "의사표시는 법률행위의 내용의 중요부분에 착오가 있는 때에는 취소할 수 있다."
instance Adjudicate MistakeAct '[Base] where
  adjudicate :: MistakeAct -> Facts MistakeAct -> Judgment '[Base]
adjudicate MistakeAct
_ Facts MistakeAct
_ =
    Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Voidable
      (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
109 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1))
      Text
"의사표시는 법률행위의 내용의 중요부분에 착오가 있는 때에는 취소할 수 있다."

-- 제109조 ① 단서
-- "그러나 그 착오가 표의자의 중대한 과실로 인한 때에는 취소하지 못한다."
instance Adjudicate MistakeAct rest
      => Adjudicate MistakeAct (Proviso ': rest) where
  adjudicate :: MistakeAct -> Facts MistakeAct -> Judgment (Proviso : rest)
adjudicate MistakeAct
act Facts MistakeAct
facts
    | CivilFact
GrossNegligence CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts MistakeAct
facts =
        Judgment rest
-> Verdict -> ArticleRef -> Text -> Judgment (Proviso : rest)
forall (prev :: [*]) l.
Judgment prev
-> Verdict -> ArticleRef -> Text -> Judgment (l : prev)
JOverride (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest MistakeAct
act Facts MistakeAct
facts)
                  Verdict
Valid
                  (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
109 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1))
                  Text
"그러나 그 착오가 표의자의 중대한 과실로 인한 때에는 취소하지 못한다."
    | Bool
otherwise =
        Judgment rest -> Judgment (Proviso : rest)
forall (prev :: [*]) l. Judgment prev -> Judgment (l : prev)
JDelegate (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest MistakeAct
act Facts MistakeAct
facts)

-- ═══════════════════════════════════════════════
-- 제110조 — 사기, 강박에 의한 의사표시
-- ═══════════════════════════════════════════════

type instance Resolvable FraudAct = '[Proviso, Base]

-- 제110조 ① "사기나 강박에 의한 의사표시는 취소할 수 있다."
instance Adjudicate FraudAct '[Base] where
  adjudicate :: FraudAct -> Facts FraudAct -> Judgment '[Base]
adjudicate FraudAct
_ Facts FraudAct
_ =
    Verdict -> ArticleRef -> Text -> Judgment '[Base]
forall l. Verdict -> ArticleRef -> Text -> Judgment '[l]
JBase Verdict
Voidable
      (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
110 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
1))
      Text
"사기나 강박에 의한 의사표시는 취소할 수 있다."

-- 제110조 ②
-- "상대방있는 의사표시에 관하여 제삼자가 사기를 행한 경우에는
--  상대방이 그 사실을 알았거나 알 수 있었을 경우에 한하여
--  그 의사표시를 취소할 수 있다."
instance Adjudicate FraudAct rest
      => Adjudicate FraudAct (Proviso ': rest) where
  adjudicate :: FraudAct -> Facts FraudAct -> Judgment (Proviso : rest)
adjudicate FraudAct
act Facts FraudAct
facts
    | CivilFact
ThirdPartyFraud CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts FraudAct
facts
      Bool -> Bool -> Bool
&& Bool -> Bool
not (CivilFact
CounterpartyKnewFraud CivilFact -> Set CivilFact -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set CivilFact
Facts FraudAct
facts) =
        Judgment rest
-> Verdict -> ArticleRef -> Text -> Judgment (Proviso : rest)
forall (prev :: [*]) l.
Judgment prev
-> Verdict -> ArticleRef -> Text -> Judgment (l : prev)
JOverride (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest FraudAct
act Facts FraudAct
facts)
                  Verdict
Valid
                  (Text -> Int -> Maybe Int -> ArticleRef
ArticleRef Text
"민법" Int
110 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
2))
                  Text
"상대방있는 의사표시에 관하여 제삼자가 사기를 행한 경우에는 상대방이 그 사실을 알았거나 알 수 있었을 경우에 한하여 그 의사표시를 취소할 수 있다."
    | Bool
otherwise =
        Judgment rest -> Judgment (Proviso : rest)
forall (prev :: [*]) l. Judgment prev -> Judgment (l : prev)
JDelegate (forall act (layers :: [*]).
Adjudicate act layers =>
act -> Facts act -> Judgment layers
adjudicate @_ @rest FraudAct
act Facts FraudAct
facts)