{-# LANGUAGE OverloadedStrings #-}

module Funcons.Operations.Sets where

import Funcons.Operations.Booleans
import Funcons.Operations.Internal hiding (set_)

import Data.List (permutations)
import qualified Data.Set as S

library :: (HasValues t, Ord t) => Library t
library :: Library t
library = [(OP, ValueOp t)] -> Library t
forall t. [(OP, ValueOp t)] -> Library t
libFromList [
    (OP
"set-empty", NullaryExpr t -> ValueOp t
forall t. NullaryExpr t -> ValueOp t
NullaryExpr NullaryExpr t
forall t. HasValues t => OpExpr t
set_empty)
  , (OP
"sets", UnaryExpr t -> ValueOp t
forall t. UnaryExpr t -> ValueOp t
UnaryExpr UnaryExpr t
forall t. HasValues t => OpExpr t -> OpExpr t
Funcons.Operations.Sets.sets) 
  , (OP
"is-in-set", BinaryExpr t -> ValueOp t
forall t. BinaryExpr t -> ValueOp t
BinaryExpr BinaryExpr t
forall t. (HasValues t, Ord t) => OpExpr t -> OpExpr t -> OpExpr t
is_in_set) 
  , (OP
"set", NaryExpr t -> ValueOp t
forall t. NaryExpr t -> ValueOp t
NaryExpr NaryExpr t
forall t. (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_)
  , (OP
"set-elements", UnaryExpr t -> ValueOp t
forall t. UnaryExpr t -> ValueOp t
UnaryExpr UnaryExpr t
forall t. HasValues t => OpExpr t -> OpExpr t
set_elements)
  , (OP
"is-subset", BinaryExpr t -> ValueOp t
forall t. BinaryExpr t -> ValueOp t
BinaryExpr BinaryExpr t
forall t. (Ord t, HasValues t) => OpExpr t -> OpExpr t -> OpExpr t
is_subset)
  , (OP
"set-insert", BinaryExpr t -> ValueOp t
forall t. BinaryExpr t -> ValueOp t
BinaryExpr BinaryExpr t
forall t. (HasValues t, Ord t) => OpExpr t -> OpExpr t -> OpExpr t
set_insert)
  , (OP
"set-unite", NaryExpr t -> ValueOp t
forall t. NaryExpr t -> ValueOp t
NaryExpr NaryExpr t
forall t. (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_unite_)
  , (OP
"set-intersect", NaryExpr t -> ValueOp t
forall t. NaryExpr t -> ValueOp t
NaryExpr NaryExpr t
forall t. (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_intersect_)
  , (OP
"set-difference", NaryExpr t -> ValueOp t
forall t. NaryExpr t -> ValueOp t
NaryExpr NaryExpr t
forall t. (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_difference_)
  , (OP
"set-size", UnaryExpr t -> ValueOp t
forall t. UnaryExpr t -> ValueOp t
UnaryExpr UnaryExpr t
forall t. (Ord t, HasValues t) => OpExpr t -> OpExpr t
set_size)
  , (OP
"some-element", UnaryExpr t -> ValueOp t
forall t. UnaryExpr t -> ValueOp t
UnaryExpr UnaryExpr t
forall t. (HasValues t, Ord t) => OpExpr t -> OpExpr t
some_element)
  , (OP
"element-not-in", BinaryExpr t -> ValueOp t
forall t. BinaryExpr t -> ValueOp t
BinaryExpr BinaryExpr t
forall t. (Ord t, HasValues t) => OpExpr t -> OpExpr t -> OpExpr t
element_not_in)
--  , ("is-set-empty", UnaryExpr is_set_empty)
  ]

sets_ :: HasValues t => [OpExpr t] -> OpExpr t
sets_ :: [OpExpr t] -> OpExpr t
sets_ = UnaryExpr t -> [OpExpr t] -> OpExpr t
forall t. UnaryExpr t -> [OpExpr t] -> OpExpr t
unaryOp UnaryExpr t
forall t. HasValues t => OpExpr t -> OpExpr t
Funcons.Operations.Sets.sets
sets :: HasValues t => OpExpr t -> OpExpr t
sets :: OpExpr t -> OpExpr t
sets = OP -> UnaryVOp t -> OpExpr t -> OpExpr t
forall t. HasValues t => OP -> UnaryVOp t -> OpExpr t -> OpExpr t
vUnaryOp OP
"sets" UnaryVOp t
forall t. HasValues t => Values t -> Result t
op
  where op :: Values t -> Result t
op (ComputationType (Type Types t
t)) = 
          t -> Result t
forall t. t -> Result t
Normal (t -> Result t) -> t -> Result 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
$ Types t -> Types t
forall t. HasValues t => Types t -> Types t
Funcons.Operations.Internal.sets Types t
t
        op Values t
_ = OP -> Result t
forall t. OP -> Result t
SortErr OP
"sets not applied to a type" 

set_empty_ :: HasValues t => [OpExpr t] -> OpExpr t
set_empty_ :: [OpExpr t] -> OpExpr t
set_empty_ = OpExpr t -> [OpExpr t] -> OpExpr t
forall t. NullaryExpr t -> [NullaryExpr t] -> NullaryExpr t
nullaryOp OpExpr t
forall t. HasValues t => OpExpr t
set_empty
set_empty :: HasValues t => OpExpr t
set_empty :: OpExpr t
set_empty = OP -> NullaryOp t -> OpExpr t
forall t. OP -> NullaryOp t -> OpExpr t
NullaryOp OP
"set-empty" (t -> NullaryOp t
forall t. t -> Result t
Normal (t -> NullaryOp t) -> t -> NullaryOp t
forall a b. (a -> b) -> a -> b
$ Values t -> t
forall t. HasValues t => Values t -> t
inject (ValueSets (Values t) -> Values t
forall t. ValueSets (Values t) -> Values t
Set ValueSets (Values t)
forall a. Set a
S.empty))

is_in_set_ :: (HasValues t, Ord t) => [OpExpr t] -> OpExpr t
is_in_set_ :: [OpExpr t] -> OpExpr t
is_in_set_ = BinaryExpr t -> [OpExpr t] -> OpExpr t
forall t. BinaryExpr t -> [OpExpr t] -> OpExpr t
binaryOp BinaryExpr t
forall t. (HasValues t, Ord t) => OpExpr t -> OpExpr t -> OpExpr t
is_in_set
is_in_set :: (HasValues t, Ord t) => OpExpr t -> OpExpr t -> OpExpr t 
is_in_set :: OpExpr t -> OpExpr t -> OpExpr t
is_in_set = OP -> BinaryOp t -> OpExpr t -> OpExpr t -> OpExpr t
forall t. OP -> BinaryOp t -> OpExpr t -> OpExpr t -> OpExpr t
BinaryOp OP
"is-in-set" BinaryOp t
forall t t. (HasValues t, HasValues t, Ord t) => t -> t -> Result t
op 
  where op :: t -> t -> Result t
op t
e' t
s' 
          | Just Values t
s <- t -> Maybe (Values t)
forall t. HasValues t => t -> Maybe (Values t)
project t
s', Just Values t
e <- t -> Maybe (Values t)
forall t. HasValues t => t -> Maybe (Values t)
project t
e' = case Values t
s of 
            Set ValueSets (Values t)
set -> 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 (Values t
e Values t -> ValueSets (Values t) -> Bool
forall a. Ord a => a -> Set a -> Bool
`S.member` ValueSets (Values t)
set)
            Values t
_       -> OP -> Result t
forall t. OP -> Result t
SortErr OP
"is-in-set(V,S) not applied to a value and a set"
          | Bool
otherwise = OP -> Result t
forall t. OP -> Result t
ProjErr OP
"is-in-set"

set_elements_ :: HasValues t => [OpExpr t] -> OpExpr t
set_elements_ :: [OpExpr t] -> OpExpr t
set_elements_ = UnaryExpr t -> [OpExpr t] -> OpExpr t
forall t. UnaryExpr t -> [OpExpr t] -> OpExpr t
unaryOp UnaryExpr t
forall t. HasValues t => OpExpr t -> OpExpr t
set_elements
set_elements :: HasValues t => OpExpr t -> OpExpr t
set_elements :: OpExpr t -> OpExpr t
set_elements = OP -> UnaryVOp t -> OpExpr t -> OpExpr t
forall t. HasValues t => OP -> UnaryVOp t -> OpExpr t -> OpExpr t
vUnaryOp OP
"set-elements" UnaryVOp t
forall t. HasValues t => Values t -> Result t
op
 where op :: Values t -> Result t
op (Set ValueSets (Values t)
s) = [Result t] -> Result t
forall t. [Result t] -> Result t
Nondeterministic ([Result t] -> Result t) -> [Result t] -> Result t
forall a b. (a -> b) -> a -> b
$ ([Values t] -> Result t) -> [[Values t]] -> [Result t]
forall a b. (a -> b) -> [a] -> [b]
map (t -> Result t
forall t. t -> Result t
Normal (t -> Result t) -> ([Values t] -> t) -> [Values t] -> Result t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Values t -> t
forall t. HasValues t => Values t -> t
inject (Values t -> t) -> ([Values t] -> Values t) -> [Values t] -> t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [t] -> Values t
forall t. HasValues t => [t] -> Values t
multi 
                                             ([t] -> Values t) -> ([Values t] -> [t]) -> [Values t] -> Values t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Values t -> t) -> [Values t] -> [t]
forall a b. (a -> b) -> [a] -> [b]
map Values t -> t
forall t. HasValues t => Values t -> t
inject) ([[Values t]] -> [Result t]) -> [[Values t]] -> [Result t]
forall a b. (a -> b) -> a -> b
$ 
                     [Values t] -> [[Values t]]
forall a. [a] -> [[a]]
permutations ([Values t] -> [[Values t]]) -> [Values t] -> [[Values t]]
forall a b. (a -> b) -> a -> b
$ ValueSets (Values t) -> [Values t]
forall a. Set a -> [a]
S.toList ValueSets (Values t)
s
       op Values t
_ = OP -> Result t
forall t. OP -> Result t
SortErr OP
"set-elements not applied to a set"

set_size_ :: (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_size_ :: [OpExpr t] -> OpExpr t
set_size_ = UnaryExpr t -> [OpExpr t] -> OpExpr t
forall t. UnaryExpr t -> [OpExpr t] -> OpExpr t
unaryOp UnaryExpr t
forall t. (Ord t, HasValues t) => OpExpr t -> OpExpr t
set_size
set_size :: (Ord t, HasValues t) => OpExpr t -> OpExpr t
set_size :: OpExpr t -> OpExpr t
set_size = OP -> UnaryVOp t -> OpExpr t -> OpExpr t
forall t. HasValues t => OP -> UnaryVOp t -> OpExpr t -> OpExpr t
vUnaryOp OP
"set-size" UnaryVOp t
forall t t. HasValues t => Values t -> Result t
op
 where op :: Values t -> Result t
op (Set ValueSets (Values t)
s) = 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
$ Integer -> Values t
forall t. Integer -> Values t
Nat (Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Int -> Integer) -> Int -> Integer
forall a b. (a -> b) -> a -> b
$ ValueSets (Values t) -> Int
forall a. Set a -> Int
S.size ValueSets (Values t)
s) 
       op Values t
_ = OP -> Result t
forall t. OP -> Result t
SortErr OP
"set-size not applied to a set"

set_intersect_ :: (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_intersect_ :: [OpExpr t] -> OpExpr t
set_intersect_ = OP -> NaryVOp t -> [OpExpr t] -> OpExpr t
forall t. HasValues t => OP -> NaryVOp t -> [OpExpr t] -> OpExpr t
vNaryOp OP
"set-intersect" NaryVOp t
forall t. (HasValues t, Ord t) => [Values t] -> Result t
op
  where op :: [Values t] -> Result t
op [] = OP -> Result t
forall t. OP -> Result t
SortErr OP
"set-intersect applied to an empty sequence of sets"
        op [Values t]
vs | (Values t -> Bool) -> [Values t] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Values t -> Bool
forall t. Values t -> Bool
isSet_ [Values t]
vs = 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
$ 
                                  ValueSets (Values t) -> Values t
forall t. ValueSets (Values t) -> Values t
Set ((ValueSets (Values t)
 -> ValueSets (Values t) -> ValueSets (Values t))
-> [ValueSets (Values t)] -> ValueSets (Values t)
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 ValueSets (Values t)
-> ValueSets (Values t) -> ValueSets (Values t)
forall a. Ord a => Set a -> Set a -> Set a
S.intersection ((Values t -> ValueSets (Values t))
-> [Values t] -> [ValueSets (Values t)]
forall a b. (a -> b) -> [a] -> [b]
map Values t -> ValueSets (Values t)
forall t. Values t -> ValueSets (Values t)
toSet [Values t]
vs))
              | Bool
otherwise = OP -> Result t
forall t. OP -> Result t
SortErr OP
"set-intersect not applied to sets"
          where isSet_ :: Values t -> Bool
isSet_ (Set ValueSets (Values t)
_) = Bool
True
                isSet_ Values t
_       = Bool
False
                toSet :: Values t -> ValueSets (Values t)
toSet (Set ValueSets (Values t)
s)  = ValueSets (Values t)
s
                toSet Values t
_        = OP -> ValueSets (Values t)
forall a. HasCallStack => OP -> a
error OP
"set-intersect toSet"

set_difference_ :: (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_difference_ :: [OpExpr t] -> OpExpr t
set_difference_ = BinaryExpr t -> [OpExpr t] -> OpExpr t
forall t. BinaryExpr t -> [OpExpr t] -> OpExpr t
binaryOp BinaryExpr t
forall t. (Ord t, HasValues t) => OpExpr t -> OpExpr t -> OpExpr t
set_difference
set_difference :: (Ord t, HasValues t) => OpExpr t -> OpExpr t -> OpExpr t
set_difference :: OpExpr t -> OpExpr t -> OpExpr t
set_difference = OP -> BinaryVOp t -> OpExpr t -> OpExpr t -> OpExpr t
forall t.
HasValues t =>
OP -> BinaryVOp t -> OpExpr t -> OpExpr t -> OpExpr t
vBinaryOp OP
"set-difference" BinaryVOp t
forall t. (HasValues t, Ord t) => Values t -> Values t -> Result t
op
  where op :: Values t -> Values t -> Result t
op (Set ValueSets (Values t)
s1) (Set ValueSets (Values t)
s2) = 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
$ ValueSets (Values t) -> Values t
forall t. ValueSets (Values t) -> Values t
Set (ValueSets (Values t)
s1 ValueSets (Values t)
-> ValueSets (Values t) -> ValueSets (Values t)
forall a. Ord a => Set a -> Set a -> Set a
`S.difference` ValueSets (Values t)
s2)
        op Values t
_ Values t
_ = OP -> Result t
forall t. OP -> Result t
SortErr OP
"set-difference not applied to two sets"

some_element_ :: (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
some_element_ :: [OpExpr t] -> OpExpr t
some_element_ = UnaryExpr t -> [OpExpr t] -> OpExpr t
forall t. UnaryExpr t -> [OpExpr t] -> OpExpr t
unaryOp UnaryExpr t
forall t. (HasValues t, Ord t) => OpExpr t -> OpExpr t
some_element
some_element :: (HasValues t, Ord t) => OpExpr t -> OpExpr t
some_element :: OpExpr t -> OpExpr t
some_element = OP -> UnaryVOp t -> OpExpr t -> OpExpr t
forall t. HasValues t => OP -> UnaryVOp t -> OpExpr t -> OpExpr t
vUnaryOp OP
"some-element" UnaryVOp t
forall t. HasValues t => Values t -> Result t
op
  where op :: Values t -> Result t
op (Set ValueSets (Values t)
s) | Bool -> Bool
not (ValueSets (Values t) -> Bool
forall a. Set a -> Bool
S.null ValueSets (Values t)
s) = [Result t] -> Result t
forall t. [Result t] -> Result t
choice ([Result t] -> Result t) -> [Result t] -> Result t
forall a b. (a -> b) -> a -> b
$ (Values t -> Result t) -> [Values t] -> [Result t]
forall a b. (a -> b) -> [a] -> [b]
map (t -> Result t
forall t. t -> Result t
Normal (t -> Result t) -> (Values t -> t) -> Values t -> Result t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Values t -> t
forall t. HasValues t => Values t -> t
inject) ([Values t] -> [Result t]) -> [Values t] -> [Result t]
forall a b. (a -> b) -> a -> b
$ ValueSets (Values t) -> [Values t]
forall a. Set a -> [a]
S.toList ValueSets (Values t)
s
                   | Bool
otherwise      = 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
forall t. Values t
null__
        op Values t
_ = OP -> Result t
forall t. OP -> Result t
SortErr OP
"some-element not applied to a set"

is_subset_ :: (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
is_subset_ :: [OpExpr t] -> OpExpr t
is_subset_ = BinaryExpr t -> [OpExpr t] -> OpExpr t
forall t. BinaryExpr t -> [OpExpr t] -> OpExpr t
binaryOp BinaryExpr t
forall t. (Ord t, HasValues t) => OpExpr t -> OpExpr t -> OpExpr t
is_subset
is_subset :: (Ord t, HasValues t) => OpExpr t -> OpExpr t -> OpExpr t
is_subset :: OpExpr t -> OpExpr t -> OpExpr t
is_subset = OP -> BinaryVOp t -> OpExpr t -> OpExpr t -> OpExpr t
forall t.
HasValues t =>
OP -> BinaryVOp t -> OpExpr t -> OpExpr t -> OpExpr t
vBinaryOp OP
"is-subset" BinaryVOp t
forall t t.
(HasValues t, Ord t) =>
Values t -> Values t -> Result t
op
  where op :: Values t -> Values t -> Result t
op (Set ValueSets (Values t)
s1) (Set ValueSets (Values t)
s2) = 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 (ValueSets (Values t)
s1 ValueSets (Values t) -> ValueSets (Values t) -> Bool
forall a. Ord a => Set a -> Set a -> Bool
`S.isSubsetOf` ValueSets (Values t)
s2)
        op Values t
_ Values t
_ = OP -> Result t
forall t. OP -> Result t
SortErr OP
"is-subset not applied to two sets"

set_ :: (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_ :: [OpExpr t] -> OpExpr t
set_ = OP -> NaryVOp t -> [OpExpr t] -> OpExpr t
forall t. HasValues t => OP -> NaryVOp t -> [OpExpr t] -> OpExpr t
vNaryOp OP
"set" NaryVOp t
forall t. (HasValues t, Ord t) => [Values t] -> Result t
op
  where op :: [Values t] -> Result t
op [Values t]
vs = 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
$ ValueSets (Values t) -> Values t
forall t. ValueSets (Values t) -> Values t
Set ([Values t] -> ValueSets (Values t)
forall a. Ord a => [a] -> Set a
S.fromList [Values t]
vs)

set_unite_ :: (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_unite_ :: [OpExpr t] -> OpExpr t
set_unite_ = OP -> NaryVOp t -> [OpExpr t] -> OpExpr t
forall t. HasValues t => OP -> NaryVOp t -> [OpExpr t] -> OpExpr t
vNaryOp OP
"set-unite" NaryVOp t
forall t. (HasValues t, Ord t) => [Values t] -> Result t
op
  where op :: [Values t] -> Result t
op [Values t]
vs | (Values t -> Bool) -> [Values t] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Values t -> Bool
forall t. Values t -> Bool
isSet_ [Values t]
vs = 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
$ ValueSets (Values t) -> Values t
forall t. ValueSets (Values t) -> Values t
Set (ValueSets (Values t) -> Values t)
-> ValueSets (Values t) -> Values t
forall a b. (a -> b) -> a -> b
$ [ValueSets (Values t)] -> ValueSets (Values t)
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
S.unions ([ValueSets (Values t)] -> ValueSets (Values t))
-> [ValueSets (Values t)] -> ValueSets (Values t)
forall a b. (a -> b) -> a -> b
$ (Values t -> ValueSets (Values t))
-> [Values t] -> [ValueSets (Values t)]
forall a b. (a -> b) -> [a] -> [b]
map Values t -> ValueSets (Values t)
forall t. Values t -> ValueSets (Values t)
unSet [Values t]
vs
              | Bool
otherwise = OP -> Result t
forall t. OP -> Result t
SortErr OP
"set-unite not applied to sets"
          where isSet_ :: Values t -> Bool
isSet_ (Set ValueSets (Values t)
s) = Bool
True
                isSet_ Values t
_       = Bool
False
                unSet :: Values t -> ValueSets (Values t)
unSet (Set ValueSets (Values t)
s) = ValueSets (Values t)
s
                unSet Values t
_       = OP -> ValueSets (Values t)
forall a. HasCallStack => OP -> a
error OP
"set-unite not applied to sets only"

set_insert_ :: (Ord t, HasValues t) => [OpExpr t] -> OpExpr t
set_insert_ :: [OpExpr t] -> OpExpr t
set_insert_ = BinaryExpr t -> [OpExpr t] -> OpExpr t
forall t. BinaryExpr t -> [OpExpr t] -> OpExpr t
binaryOp BinaryExpr t
forall t. (HasValues t, Ord t) => OpExpr t -> OpExpr t -> OpExpr t
set_insert
set_insert :: (HasValues t, Ord t) => OpExpr t -> OpExpr t -> OpExpr t
set_insert :: OpExpr t -> OpExpr t -> OpExpr t
set_insert = OP -> BinaryVOp t -> OpExpr t -> OpExpr t -> OpExpr t
forall t.
HasValues t =>
OP -> BinaryVOp t -> OpExpr t -> OpExpr t -> OpExpr t
vBinaryOp OP
"set-insert" BinaryVOp t
forall t. (HasValues t, Ord t) => Values t -> Values t -> Result t
op
  where op :: Values t -> Values t -> Result t
op Values t
e (Set ValueSets (Values t)
s) = 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
$ ValueSets (Values t) -> Values t
forall t. ValueSets (Values t) -> Values t
Set (Values t
e Values t -> ValueSets (Values t) -> ValueSets (Values t)
forall a. Ord a => a -> Set a -> Set a
`S.insert` ValueSets (Values t)
s)
        op Values t
_ Values t
_ = OP -> Result t
forall t. OP -> Result t
SortErr OP
"second argument of set-insert is not a set"

element_not_in_ :: (HasValues t, Ord t) => [OpExpr t] -> OpExpr t 
element_not_in_ :: [OpExpr t] -> OpExpr t
element_not_in_ = BinaryExpr t -> [OpExpr t] -> OpExpr t
forall t. BinaryExpr t -> [OpExpr t] -> OpExpr t
binaryOp BinaryExpr t
forall t. (Ord t, HasValues t) => OpExpr t -> OpExpr t -> OpExpr t
element_not_in
element_not_in :: (Ord t, HasValues t) => OpExpr t -> OpExpr t -> OpExpr t
element_not_in :: OpExpr t -> OpExpr t -> OpExpr t
element_not_in = OP -> BinaryVOp t -> OpExpr t -> OpExpr t -> OpExpr t
forall t.
HasValues t =>
OP -> BinaryVOp t -> OpExpr t -> OpExpr t -> OpExpr t
vBinaryOp OP
"element-not-in" BinaryVOp t
forall t t.
(HasValues t, Ord t) =>
Values t -> Values t -> Result t
op
  where op :: Values t -> Values t -> Result t
op (ComputationType (Type Types t
ty)) (Set ValueSets (Values t)
set) = case Types t
ty of 
          Types t
Atoms -> 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
$ [Values t] -> Values t
forall a. [a] -> a
head [Values t]
atoms
          Types t
_     -> OP -> Result t
forall a. HasCallStack => OP -> a
error OP
"missing case for `element-not-in`"
          where atoms :: [Values t]
atoms    = (Values t -> Bool) -> [Values t] -> [Values t]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile ((Values t -> ValueSets (Values t) -> Bool)
-> ValueSets (Values t) -> Values t -> Bool
forall a b c. (a -> b -> c) -> b -> a -> c
flip Values t -> ValueSets (Values t) -> Bool
forall a. Ord a => a -> Set a -> Bool
S.member ValueSets (Values t)
set) ([Values t] -> [Values t]) -> [Values t] -> [Values t]
forall a b. (a -> b) -> a -> b
$ 
                              (Integer -> Values t) -> [Integer] -> [Values t]
forall a b. (a -> b) -> [a] -> [b]
map (OP -> Values t
forall t. OP -> Values t
Atom (OP -> Values t) -> (Integer -> OP) -> Integer -> Values t
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (OP
"@" OP -> OP -> OP
forall a. [a] -> [a] -> [a]
++) (OP -> OP) -> (Integer -> OP) -> Integer -> OP
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> OP
forall a. Show a => a -> OP
show) [Integer
1..]
        op Values t
_ Values t
_ = OP -> Result t
forall t. OP -> Result t
SortErr OP
"element-not-in not applied to a type and a set"