1 {-# LANGUAGE ExistentialQuantification #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
5 {-# LANGUAGE MultiParamTypeClasses #-}
6 {-# LANGUAGE OverloadedStrings #-}
7 {-# LANGUAGE Rank2Types #-}
8 {-# LANGUAGE ScopedTypeVariables #-}
9 {-# LANGUAGE TypeFamilies #-}
10 {-# LANGUAGE UndecidableInstances #-}
11 module Language.LOL.Symantic.Expr.Bool where
13 import Data.Proxy (Proxy(..))
14 import Prelude hiding (and, not, or)
16 import Language.LOL.Symantic.Raw
17 import Language.LOL.Symantic.Type
18 import Language.LOL.Symantic.Expr.Common
19 import Language.LOL.Symantic.Expr.Lambda
20 import Language.LOL.Symantic.Repr.Dup
24 -- | Symantics combinable with 'Type_Bool'.
25 class Sym_Bool repr where
26 bool :: Bool -> repr Bool
27 not :: repr Bool -> repr Bool
28 and :: repr Bool -> repr Bool -> repr Bool
29 or :: repr Bool -> repr Bool -> repr Bool
30 xor :: repr Bool -> repr Bool -> repr Bool
31 xor x y = (x `or` y) `and` not (x `and` y)
33 instance -- Sym_Bool Dup
36 ) => Sym_Bool (Dup r1 r2) where
37 bool x = bool x `Dup` bool x
38 not (x1 `Dup` x2) = not x1 `Dup` not x2
39 and (x1 `Dup` x2) (y1 `Dup` y2) = and x1 y1 `Dup` and x2 y2
40 or (x1 `Dup` x2) (y1 `Dup` y2) = or x1 y1 `Dup` or x2 y2
41 xor (x1 `Dup` x2) (y1 `Dup` y2) = xor x1 y1 `Dup` xor x2 y2
44 data Expr_Bool (root:: *)
45 type instance Root_of_Expr (Expr_Bool root) = root
46 type instance Type_of_Expr (Expr_Bool root) = Type_Bool
47 type instance Sym_of_Expr (Expr_Bool root) repr = Sym_Bool repr
48 type instance Error_of_Expr raw (Expr_Bool root) = Error_Expr_Bool raw
50 instance -- Sym_from Raw Expr_Bool
51 ( Type_from Raw (Type_Root_of_Expr root)
54 , Type_Root_Lift Type_Bool (Type_Root_of_Expr root)
55 , Error_Type_Lift (Error_Type_Fun Raw)
56 (Error_of_Type Raw (Type_Root_of_Expr root))
57 , Error_Expr_Lift (Error_Expr_Lambda (Error_of_Type Raw (Type_Root_of_Expr root))
58 ( Type_Root_of_Expr root)
60 (Error_of_Expr Raw root)
61 , Error_Expr_Lift (Error_Expr_Read Raw)
62 (Error_of_Expr Raw root)
64 , Type_Cons_Unlift Type_Bool (Type_of_Expr root)
66 , Root_of_Expr root ~ root
67 -- , Root_of_Type (Type_Root_of_Expr root) ~ Type_Root_of_Expr root
68 ) => Sym_from Raw (Expr_Bool root) where
69 sym_from _px_ex ctx raw k =
74 case read_safe raw_bool of
75 Left err -> Left $ Just $ error_expr_lift
76 (Error_Expr_Read err raw :: Error_Expr_Read Raw)
78 k type_bool $ Forall_Repr_with_Context $
80 _ -> Left $ Just $ error_lambda_lift $
81 Error_Expr_Fun_Wrong_number_of_arguments 3 raw
82 Raw "not" raws -> unary_from raws not
83 Raw "and" raws -> binary_from raws and
84 Raw "or" raws -> binary_from raws or
85 Raw "xor" raws -> binary_from raws xor
89 (op::forall repr. Sym_Bool repr
90 => repr Bool -> repr Bool) =
93 sym_from (Proxy::Proxy root) ctx raw_x $
94 \(ty_x::Type_Root_of_Expr root h_x) (Forall_Repr_with_Context x) ->
95 case type_cons_unlift $ unType_Root ty_x of
96 Just (Type_Bool::Type_Bool (Type_Root_of_Expr root) h_x) ->
97 k ty_x $ Forall_Repr_with_Context (op . x)
98 _ -> Left $ Just $ error_lambda_lift $
99 Error_Expr_Fun_Argument_mismatch
100 (Exists_Type type_bool)
101 (Exists_Type ty_x) raw
102 _ -> Left $ Just $ error_lambda_lift $
103 Error_Expr_Fun_Wrong_number_of_arguments 1 raw
105 (op::forall repr. Sym_Bool repr
106 => repr Bool -> repr Bool -> repr Bool) =
109 sym_from (Proxy::Proxy root) ctx raw_x $
110 \(ty_x::Type_Root_of_Expr root h_x) (Forall_Repr_with_Context x) ->
111 sym_from (Proxy::Proxy root) ctx raw_y $
112 \(ty_y::Type_Root_of_Expr root h_y) (Forall_Repr_with_Context y) ->
113 case type_cons_unlift $ unType_Root ty_x of
114 Just (Type_Bool::Type_Bool (Type_Root_of_Expr root) h_x) ->
115 case type_cons_unlift $ unType_Root ty_y of
116 Just (Type_Bool::Type_Bool (Type_Root_of_Expr root) h_y) ->
117 k ty_x $ Forall_Repr_with_Context $
119 Nothing -> Left $ Just $ error_lambda_lift $
120 Error_Expr_Fun_Argument_mismatch
121 (Exists_Type type_bool)
122 (Exists_Type ty_y) raw
123 Nothing -> Left $ Just $ error_lambda_lift $
124 Error_Expr_Fun_Argument_mismatch
125 (Exists_Type type_bool)
126 (Exists_Type ty_x) raw
127 _ -> Left $ Just $ error_lambda_lift $
128 Error_Expr_Fun_Wrong_number_of_arguments 2 raw
130 :: Error_Expr_Lambda (Error_of_Type Raw (Type_Root_of_Expr root)) (Type_Root_of_Expr root) Raw
131 -> Error_of_Expr Raw root
132 error_lambda_lift = error_expr_lift
135 :: Error_Expr_Bool Raw
136 -> Error_of_Expr Raw root
137 error_bool_lift = error_expr_lift
140 -- ** Type 'Expr_Lambda_Bool'
141 -- | Convenient alias.
142 type Expr_Lambda_Bool lam = Expr_Root (Expr_Cons (Expr_Lambda lam) Expr_Bool)
144 expr_lambda_bool_from
146 Sym_from raw (Expr_Lambda_Bool lam)
149 -> Either (Maybe (Error_of_Expr raw (Expr_Lambda_Bool lam)))
150 (Exists_Type_and_Repr (Type_Root_of_Expr (Expr_Lambda_Bool lam))
151 (Forall_Repr (Expr_Lambda_Bool lam)))
152 expr_lambda_bool_from _px_lam raw =
154 (Proxy::Proxy (Expr_Lambda_Bool lam))
155 Context_Empty raw $ \ty (Forall_Repr_with_Context repr) ->
156 Right $ Exists_Type_and_Repr ty $
157 Forall_Repr $ repr Context_Empty
159 -- * Type 'Error_Expr_Bool'
160 data Error_Expr_Bool raw