packages feed

unbound-0.3: examples/Set.hs

{-# LANGUAGE TemplateHaskell, UndecidableInstances, ExistentialQuantification,
    TypeOperators, GADTs, TypeSynonymInstances, FlexibleInstances,
    ScopedTypeVariables, MultiParamTypeClasses, StandaloneDeriving
 #-}

module Set where

import Generics.RepLib
import Unbound.LocallyNameless
import Data.List
import Data.Set

data Ty = All (Bind [Name Ty] Ty)
        | Var (Name Ty)
        | Arr Ty Ty deriving Show

$(derive [''Ty])

$(derive_abstract [''Set])

instance Alpha Ty

a, b, c :: Name Ty
a = s2n "a"
b = s2n "b"
c = s2n "c"

sall :: [Name Ty] -> Ty -> Ty
sall ns t = All (setbind ns t)

s1 = sall [a, b] (Arr (Var a) (Var b))
s2 = sall [a, b] (Arr (Var b) (Var a))
s3 = sall [b, a] (Arr (Var a) (Var b))
s4 = sall [b, a] (Arr (Var b) (Var a))
s5 = sall [b, a, c] (Arr (Var b) (Var a))
s6 = sall [a, c] (Arr (Var a) (Var c))

pall :: [Name Ty] -> Ty -> Ty
pall ns t = All (permbind ns t)

p1 = pall [a, b] (Arr (Var a) (Var b))
p2 = pall [a, b] (Arr (Var b) (Var a))
p3 = pall [b, a] (Arr (Var a) (Var b))
p4 = pall [b, a] (Arr (Var b) (Var a))
p5 = pall [b, a, c] (Arr (Var b) (Var a))
p6 = pall [a, c] (Arr (Var a) (Var c))



assert :: String -> Bool -> IO ()
assert s True  = return ()
assert s False = print ("Assertion " ++ s ++ " failed")

main :: IO ()
main = do
  assert "s1" $ s1 `aeq` s2
  assert "s2" $ s1 `aeq` s3
  assert "s3" $ s1 `aeq` s4
  assert "s4" $ s1 `aeq` s5
  assert "s5" $ s1 `aeq` s6

  assert "a11" $ p1 `aeq` p2
  assert "a12" $ p1 `aeq` p3
  assert "a13" $ p1 `aeq` p4
  assert "a14" $ not (p1 `aeq` p5)
  assert "a15" $ p1 `aeq` p6