1 {-# LANGUAGE DefaultSignatures #-}
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 -- | Expression for 'Bool'.
12 module Language.LOL.Symantic.Expr.Bool where
14 import Data.Proxy (Proxy(..))
15 import Data.Type.Equality ((:~:)(Refl))
16 import Prelude hiding (and, not, or)
18 import Language.LOL.Symantic.AST
19 import Language.LOL.Symantic.Type
20 import Language.LOL.Symantic.Expr.Common
21 import Language.LOL.Symantic.Expr.Lambda
22 import Language.LOL.Symantic.Repr.Dup
23 import Language.LOL.Symantic.Trans.Common
28 class Sym_Bool repr where
29 bool :: Bool -> repr Bool
30 not :: repr Bool -> repr Bool
31 and :: repr Bool -> repr Bool -> repr Bool
32 or :: repr Bool -> repr Bool -> repr Bool
33 xor :: repr Bool -> repr Bool -> repr Bool
34 xor x y = (x `or` y) `and` not (x `and` y)
36 default bool :: Trans t repr => Bool -> t repr Bool
37 default not :: Trans t repr => t repr Bool -> t repr Bool
38 default and :: Trans t repr => t repr Bool -> t repr Bool -> t repr Bool
39 default or :: Trans t repr => t repr Bool -> t repr Bool -> t repr Bool
40 bool = trans_lift . bool
45 instance -- Sym_Bool Dup
48 ) => Sym_Bool (Dup r1 r2) where
49 bool x = bool x `Dup` bool x
50 not (x1 `Dup` x2) = not x1 `Dup` not x2
51 and (x1 `Dup` x2) (y1 `Dup` y2) = and x1 y1 `Dup` and x2 y2
52 or (x1 `Dup` x2) (y1 `Dup` y2) = or x1 y1 `Dup` or x2 y2
53 xor (x1 `Dup` x2) (y1 `Dup` y2) = xor x1 y1 `Dup` xor x2 y2
57 data Expr_Bool (root:: *)
58 type instance Root_of_Expr (Expr_Bool root) = root
59 type instance Type_of_Expr (Expr_Bool root) = Type_Bool
60 type instance Sym_of_Expr (Expr_Bool root) repr = Sym_Bool repr
61 type instance Error_of_Expr ast (Expr_Bool root) = ()
63 instance -- Expr_from AST Expr_Bool
64 ( Type_from AST (Type_Root_of_Expr root)
67 , Type_Root_Lift Type_Bool (Type_Root_of_Expr root)
68 , Error_Expr_Lift (Error_Expr (Error_of_Type AST (Type_Root_of_Expr root))
69 ( Type_Root_of_Expr root)
71 (Error_of_Expr AST root)
73 , Type_Unlift Type_Bool (Type_of_Expr root)
75 , Root_of_Expr root ~ root
77 , Implicit_HBool (Is_Last_Expr (Expr_Bool root) root)
78 ) => Expr_from AST (Expr_Bool root) where
79 expr_from px_ex ctx ast k =
84 case read_safe ast_bool of
85 Left err -> Left $ error_expr px_ex $ Error_Expr_Read err ast
87 k type_bool $ Forall_Repr_with_Context $
89 _ -> Left $ error_expr px_ex $
90 Error_Expr_Wrong_number_of_arguments ast 3
91 AST "not" asts -> unary_from asts not
92 AST "and" asts -> binary_from asts and
93 AST "or" asts -> binary_from asts or
94 AST "xor" asts -> binary_from asts xor
95 _ -> Left $ error_expr_unsupported px_ex ast
98 (op::forall repr. Sym_Bool repr
99 => repr Bool -> repr Bool) =
102 expr_from (Proxy::Proxy root) ctx ast_x $ \ty_x (Forall_Repr_with_Context x) ->
103 when_type_eq px_ex ast type_bool ty_x $ \Refl ->
104 k ty_x $ Forall_Repr_with_Context (op . x)
105 _ -> Left $ error_expr px_ex $
106 Error_Expr_Wrong_number_of_arguments ast 1
108 (op::forall repr. Sym_Bool repr
109 => repr Bool -> repr Bool -> repr Bool) =
112 expr_from (Proxy::Proxy root) ctx ast_x $ \ty_x (Forall_Repr_with_Context x) ->
113 expr_from (Proxy::Proxy root) ctx ast_y $ \ty_y (Forall_Repr_with_Context y) ->
114 when_type_eq px_ex ast type_bool ty_x $ \Refl ->
115 when_type_eq px_ex ast type_bool ty_y $ \Refl ->
116 k ty_x $ Forall_Repr_with_Context $
118 _ -> Left $ error_expr px_ex $
119 Error_Expr_Wrong_number_of_arguments ast 2
121 -- ** Type 'Expr_Lambda_Bool'
122 -- | Convenient alias.
123 type Expr_Lambda_Bool lam = Expr_Root (Expr_Alt (Expr_Lambda lam) Expr_Bool)
125 -- | Convenient alias around 'expr_from'.
126 expr_lambda_bool_from
128 Expr_from ast (Expr_Lambda_Bool lam)
131 -> Either (Error_of_Expr ast (Expr_Lambda_Bool lam))
132 (Exists_Type_and_Repr (Type_Root_of_Expr (Expr_Lambda_Bool lam))
133 (Forall_Repr (Expr_Lambda_Bool lam)))
134 expr_lambda_bool_from _px_lam ast =
136 (Proxy::Proxy (Expr_Lambda_Bool lam))
137 Context_Empty ast $ \ty (Forall_Repr_with_Context repr) ->
138 Right $ Exists_Type_and_Repr ty $
139 Forall_Repr $ repr Context_Empty