{-# LANGUAGE OverloadedStrings #-}

module Funcons.Operations.Booleans where

import Funcons.Operations.Internal

library :: (HasValues t, Eq t) => Library t
library :: Library t
library = [(OP, ValueOp t)] -> Library t
forall t. [(OP, ValueOp t)] -> Library t
libFromList [
    (OP
"is-equal", BinaryExpr t -> ValueOp t
forall t. BinaryExpr t -> ValueOp t
BinaryExpr BinaryExpr t
forall t. (HasValues t, Eq t) => OpExpr t -> OpExpr t -> OpExpr t
is_equal)
--  , ("booleans", NullaryExpr booleans_)
--  , ("and", BinaryExpr stepAnd)
  ]

tobool :: Bool -> Values t 
tobool :: Bool -> Values t
tobool Bool
True   = Name -> [t] -> Values t
forall t. Name -> [t] -> Values t
ADTVal Name
"true" []
tobool Bool
False  = Name -> [t] -> Values t
forall t. Name -> [t] -> Values t
ADTVal Name
"false" [] 

frombool :: (Values t) -> Maybe Bool
frombool :: Values t -> Maybe Bool
frombool (ADTVal Name
"true" []) = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True
frombool (ADTVal Name
"false" []) = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
False
frombool Values t
_ = Maybe Bool
forall a. Maybe a
Nothing


{-
and_ :: HasValues t => [OpExpr t] -> OpExpr t 
and_ = binaryOp stepAnd
stepAnd :: HasValues t => OpExpr t -> OpExpr t -> OpExpr t
stepAnd = vBinaryOp "and" op
  where op x y = case (frombool x, frombool y) of 
          (Just b1, Just b2) -> Normal $ inject $ tobool (b1 && b2)
          _ -> SortErr "and not applied to two booleans"
-}
booleans_ :: HasValues t => OpExpr t
booleans_ :: OpExpr t
booleans_ = OP -> NullaryVOp t -> OpExpr t
forall t. OP -> NullaryVOp t -> OpExpr t
vNullaryOp OP
"booleans" (t -> NullaryVOp t
forall t. t -> Result t
Normal (t -> NullaryVOp t) -> t -> NullaryVOp t
forall a b. (a -> b) -> a -> b
$ Types t -> t
forall t. HasTypes t => Types t -> t
injectT (Types t -> t) -> Types t -> t
forall a b. (a -> b) -> a -> b
$ Name -> [t] -> Types t
forall t. Name -> [t] -> Types t
ADT Name
"booleans" [])

true_ :: HasValues t => Values t 
true_ :: Values t
true_ = Bool -> Values t
forall t. Bool -> Values t
tobool Bool
True

false_ :: HasValues t => Values t 
false_ :: Values t
false_ = Bool -> Values t
forall t. Bool -> Values t
tobool Bool
False 


is_equal_ :: (HasValues t, Eq t) => [OpExpr t] -> OpExpr t
is_equal_ :: [OpExpr t] -> OpExpr t
is_equal_ = BinaryExpr t -> [OpExpr t] -> OpExpr t
forall t. BinaryExpr t -> [OpExpr t] -> OpExpr t
binaryOp BinaryExpr t
forall t. (HasValues t, Eq t) => OpExpr t -> OpExpr t -> OpExpr t
is_equal
is_equal :: (HasValues t, Eq t) => OpExpr t -> OpExpr t -> OpExpr t
is_equal :: OpExpr t -> OpExpr t -> OpExpr t
is_equal = OP -> BinaryOp t -> OpExpr t -> OpExpr t -> OpExpr t
forall t. OP -> BinaryOp t -> OpExpr t -> OpExpr t -> OpExpr t
BinaryOp OP
"is-equal" BinaryOp t
forall t. (Eq t, HasValues t) => t -> t -> Result t
op 
  where op :: (Eq t, HasValues t) => t -> t -> Result t
        op :: t -> t -> Result t
op t
x t
y = t -> Result t
forall t. t -> Result t
Normal (t -> Result t) -> t -> Result t
forall a b. (a -> b) -> a -> b
$ Values t -> t
forall t. HasValues t => Values t -> t
inject (Values t -> t) -> Values t -> t
forall a b. (a -> b) -> a -> b
$ Bool -> Values t
forall t. Bool -> Values t
tobool (t
x t -> t -> Bool
forall a. Eq a => a -> a -> Bool
== t
y)