funcons-tools-0.1.0.0: manual/Funcons/Core/Values/Composite/Collections/Sets.hs
{-# LANGUAGE OverloadedStrings #-}
module Funcons.Core.Values.Composite.Collections.Sets where
import Funcons.EDSL
import Funcons.Core.Values.Primitive.BoolBuiltin
import qualified Data.Set as S
library = libFromList [
("set", ValueOp stepSet)
, ("set-empty", NullaryFuncon (rewritten (Set S.empty)))
, ("set-insert", ValueOp stepSet_Insert)
, ("set-unite", ValueOp set_unite_op)
, ("set-intersect", ValueOp set_intersect_op)
, ("set-difference", ValueOp set_difference_op)
, ("set-size", ValueOp set_size_op)
, ("is-in-set", ValueOp stepIsInSet)
, ("some-element", ValueOp stepSome_Element)
, ("is-set-empty", ValueOp is_set_empty_op)
, ("set-to-list", ValueOp stepSetToList)
, ("list-to-set", ValueOp stepList_To_Set)
, ("is-subset", ValueOp stepIs_Subset)
]
set_to_list = applyFuncon "set-to-list"
stepSetToList [Set s] = rewriteTo $ FValue $ List (S.toList s)
stepSetToList vs = sortErr (set_to_list (map FValue vs)) "set-to-list not applied to a set"
is_set_empty = applyFuncon "is-set-empty"
is_set_empty_op [Set s] = rewriteTo $ FValue $ tobool (null s)
is_set_empty_op vs = sortErr (is_set_empty (map FValue vs)) "is-set-empty not applied to a set"
set_size = applyFuncon "set-size"
set_size_op [Set s] = rewriteTo $ int_ (S.size s)
set_size_op vs = sortErr (set_size (map FValue vs)) "set-size not applied to a set"
set_intersect = applyFuncon "set-intersect"
set_intersect_op [] = rewriteTo $ FValue $ Set S.empty
set_intersect_op vs
| all isSet_ vs = rewriteTo $ FValue $ Set (foldr1 S.intersection (map toSet vs))
| otherwise = sortErr (set_intersect (map FValue vs)) "set-intersect not applied to sets"
where isSet_ (Set _) = True
isSet_ _ = False
toSet (Set s) = s
toSet _ = error "set-intersect toSet"
set_difference = applyFuncon "set-difference"
set_difference_op [Set s1, Set s2] = rewriteTo $ FValue $ Set (s1 `S.difference` s2)
set_difference_op vs = sortErr (set_difference (map FValue vs))
"set-difference not applied to two sets"
some_element = applyFuncon "some-element"
stepSome_Element [Set s] | not (null s) = rewriteTo $ FValue $ S.findMax s
stepSome_Element vs = sortErr (some_element (map FValue vs)) "some-element not applied to a set"
is_subset = applyFuncon "is-subset"
stepIs_Subset [Set s1, Set s2] = rewriteTo $ FValue $ tobool (s1 `S.isSubsetOf` s2)
stepIs_Subset vs = sortErr (is_subset (map FValue vs)) "is-subset not applied to two sets"
stepSet :: [Values] -> Rewrite Rewritten
stepSet vs = rewriteTo $ FValue $ Set (S.fromList vs)
stepIsInSet [e,Set s] = rewriteTo $ FValue $ tobool (e `S.member` s)
stepIsInSet vs = sortErr (applyFuncon "is-in-set" (map FValue vs)) "sort check: is-in-set(_,_)"
set_unite = applyFuncon "set-unite"
set_unite_op :: [Values] -> Rewrite Rewritten
set_unite_op vs | all isSet_ vs = rewriteTo $ FValue $ Set $ S.unions $ map unSet vs
| otherwise = sortErr (set_unite (map FValue vs)) "set-unite not applied to sets"
where isSet_ (Set s) = True
isSet_ _ = False
unSet (Set s) = s
unSet _ = error "set-unite not applied to sets only"
set_insert = applyFuncon "set-insert"
stepSet_Insert [e,Set s] = rewriteTo $ FValue $ Set (e `S.insert` s)
stepSet_Insert vs = sortErr (set_insert (map FValue vs)) "sort check: set-insert(_,_)"
list_to_set = applyFuncon "list-to-set"
stepList_To_Set [List l] = rewriteTo $ FValue $ Set $ S.fromList l
stepList_To_Set vs = sortErr (list_to_set (map FValue vs)) "list-to-set not applied to a list"