packages feed

eflint-3.0.0.1: src/Language/EFLINT/Binders.hs

module Language.EFLINT.Binders where

import Language.EFLINT.Spec

import qualified Data.Set as S

class HasVars a where
  free :: Spec -> a -> S.Set Var

instance HasVars a => HasVars [a] where
  free spec as = S.unions (map (free spec) as)

instance HasVars Term where
  free spec t = case t of
    BoolLit _   -> S.empty
    IntLit _    -> S.empty
    StringLit _ -> S.empty
    CurrentTime -> S.empty

    Ref v       -> S.singleton v
    App d args  -> case fmap domain (find_decl spec d) of
                    Just (Products xs)  -> (S.fromList xs `S.difference` S.fromList (map fst replacements))
                                              `S.union` free spec (map snd replacements)
                      where replacements = make_substitutions_of xs args 
                    _                   -> free spec (either id (map (\(Rename p q) -> q)) args)

    Not t       -> free spec t
    Present t   -> free spec t
    Violated t  -> free spec t
    Enabled t  -> free spec t
    Project t x -> free spec t
    Tag t x     -> free spec t
    Untag t     -> free spec t

    And t1 t2   -> free spec t1 `S.union` free spec t2
    Or  t1 t2   -> free spec t1 `S.union` free spec t2
    Leq t1 t2   -> free spec t1 `S.union` free spec t2
    Geq t1 t2   -> free spec t1 `S.union` free spec t2
    Ge  t1 t2   -> free spec t1 `S.union` free spec t2
    Le  t1 t2   -> free spec t1 `S.union` free spec t2
    Mult t1 t2  -> free spec t1 `S.union` free spec t2
    Mod t1 t2   -> free spec t1 `S.union` free spec t2
    Div  t1 t2  -> free spec t1 `S.union` free spec t2
    Sub t1 t2   -> free spec t1 `S.union` free spec t2
    Add t1 t2   -> free spec t1 `S.union` free spec t2
    Eq  t1 t2   -> free spec t1 `S.union` free spec t2
    Neq t1 t2   -> free spec t1 `S.union` free spec t2
    When t1 t2  -> free spec t1 `S.union` free spec t2

    Exists xs t -> free spec t `S.difference` S.fromList xs
    Forall xs t -> free spec t `S.difference` S.fromList xs
    Count  xs t -> free spec t `S.difference` S.fromList xs
    Max    xs t -> free spec t `S.difference` S.fromList xs
    Min    xs t -> free spec t `S.difference` S.fromList xs
    Sum    xs t -> free spec t `S.difference` S.fromList xs