--- Non ci sono i commenti al codice, ma vanno messi!!!

data SVar = SVar Int
  deriving(Show)

instance Eq SVar  where
  (SVar i) == (SVar j)     =  i==j

data LTerm = Var SVar | App LTerm LTerm | Lambda SVar LTerm
  deriving(Show)

data Set a = Set [a]
  deriving(Show)

union (Set s1) (Set s2) = Set ([ y | y<-s1, not (elem y s2) ]++s2)

minus (Set s1) (Set s2) = Set [ y | y<-s1, not (elem y s2) ] 

bv :: LTerm -> (Set SVar)

bv (Var x) = Set []

bv (App m n) = union (bv m) (bv n)

bv (Lambda x m) = union (bv m) (Set [x])


fv :: LTerm -> (Set SVar)

fv (Var x) = Set [x]

fv (App m n) = union (fv m) (fv n)

fv (Lambda x m) = minus (fv m) (Set [x])


-- example

x = SVar 0
y = SVar 1
z = SVar 2
t = SVar 3

lt1 = (Lambda x (Lambda z (App (App (Var x) (Var y)) (Lambda z (App (Var z) (Var t))))))

