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_Type_Lift (Error_Type_Fun AST)
69 (Error_of_Type AST (Type_Root_of_Expr root))
70 , Error_Expr_Lift (Error_Expr (Error_of_Type AST (Type_Root_of_Expr root))
71 ( Type_Root_of_Expr root)
73 (Error_of_Expr AST root)
75 , Type_Unlift Type_Bool (Type_of_Expr root)
77 , Root_of_Expr root ~ root
79 , Implicit_HBool (Is_Last_Expr (Expr_Bool root) root)
80 ) => Expr_from AST (Expr_Bool root) where
81 expr_from px_ex ctx ast k =
86 case read_safe ast_bool of
87 Left err -> Left $ error_expr px_ex $ Error_Expr_Read err ast
89 k type_bool $ Forall_Repr_with_Context $
91 _ -> Left $ error_expr px_ex $
92 Error_Expr_Wrong_number_of_arguments 3 ast
93 AST "not" asts -> unary_from asts not
94 AST "and" asts -> binary_from asts and
95 AST "or" asts -> binary_from asts or
96 AST "xor" asts -> binary_from asts xor
98 case hbool :: HBool (Is_Last_Expr (Expr_Bool root) root) of
99 HTrue -> error_expr px_ex $ Error_Expr_Unsupported ast
100 HFalse -> error_expr px_ex $ Error_Expr_Unsupported_here ast
103 (op::forall repr. Sym_Bool repr
104 => repr Bool -> repr Bool) =
107 expr_from (Proxy::Proxy root) ctx ast_x $ \ty_x (Forall_Repr_with_Context x) ->
108 when_type_eq px_ex ast type_bool ty_x $ \Refl ->
109 k ty_x $ Forall_Repr_with_Context (op . x)
110 _ -> Left $ error_expr px_ex $
111 Error_Expr_Wrong_number_of_arguments 1 ast
113 (op::forall repr. Sym_Bool repr
114 => repr Bool -> repr Bool -> repr Bool) =
117 expr_from (Proxy::Proxy root) ctx ast_x $ \ty_x (Forall_Repr_with_Context x) ->
118 expr_from (Proxy::Proxy root) ctx ast_y $ \ty_y (Forall_Repr_with_Context y) ->
119 when_type_eq px_ex ast type_bool ty_x $ \Refl ->
120 when_type_eq px_ex ast type_bool ty_y $ \Refl ->
121 k ty_x $ Forall_Repr_with_Context $
123 _ -> Left $ error_expr px_ex $
124 Error_Expr_Wrong_number_of_arguments 2 ast
126 -- ** Type 'Expr_Lambda_Bool'
127 -- | Convenient alias.
128 type Expr_Lambda_Bool lam = Expr_Root (Expr_Alt (Expr_Lambda lam) Expr_Bool)
130 -- | Convenient alias around 'expr_from'.
131 expr_lambda_bool_from
133 Expr_from ast (Expr_Lambda_Bool lam)
136 -> Either (Error_of_Expr ast (Expr_Lambda_Bool lam))
137 (Exists_Type_and_Repr (Type_Root_of_Expr (Expr_Lambda_Bool lam))
138 (Forall_Repr (Expr_Lambda_Bool lam)))
139 expr_lambda_bool_from _px_lam ast =
141 (Proxy::Proxy (Expr_Lambda_Bool lam))
142 Context_Empty ast $ \ty (Forall_Repr_with_Context repr) ->
143 Right $ Exists_Type_and_Repr ty $
144 Forall_Repr $ repr Context_Empty