module Feldspar.Core.Functions.Logic where

import Feldspar.Core.Types
import Feldspar.Core.Representation
import Feldspar.Core.Constructs

infixr 3 &&
infixr 3 &&*
infixr 2 ||
infixr 2 ||*

not :: Data Bool -> Data Bool
not = function1 "not" fullProp Prelude.not

(&&) :: Data Bool -> Data Bool -> Data Bool
x && y = case (viewLiteral x, viewLiteral y) of
           (Just True, _) -> y
           (Just False,_) -> false
           (_, Just True) -> x
           (_,Just False) -> false
           _              -> function2 "(&&)" fullProp (Prelude.&&) x y

(||) :: Data Bool -> Data Bool -> Data Bool
x || y = case (viewLiteral x, viewLiteral y) of
           (Just True, _) -> true
           (Just False,_) -> y
           (_, Just True) -> true
           (_,Just False) -> x
           _              -> function2 "(||)" fullProp (Prelude.||) x y

-- | Lazy conjunction, second argument only evaluated if necessary
(&&*) :: Data Bool -> Data Bool -> Data Bool
a &&* b = condition a b false

-- | Lazy disjunction, second argument only evaluated if necessary
(||*) :: Data Bool -> Data Bool -> Data Bool
a ||* b = condition a true b