(datatype VarT)
(datatype Term)
(constructor App (Term Term) Term)
(constructor Lam (VarT Term) Term)
(constructor Var (VarT) Term)
(constructor Let (VarT Term Term) Term)
(constructor Add (Term Term) Term)
(constructor Num (i64) Term)
(constructor CaseSplit (Term Term Term) Term)
(constructor Cons (Term Term) Term)
(constructor Nil () Term)
(constructor V (String) VarT)
(sort StringSet (Set VarT))
(function freer (Term) StringSet :merge (set-intersect old new))
;;(rule ((= e (App e1 e2))
;; (= (freer e1) fv1)
;; (= (freer e2) fv2))
;; ((set (freer e) (set-union fv1 fv2))))
(rule ((= e (App e1 e2))
(= fvar1 (freer e1))
(= fvar1 fv1)
(= fvar2 (freer e2))
(= fvar2 fv2))
((set (freer e) (set-union fv1 fv2))))
(rule ((= e (Var v))) ((set (freer e) (set-insert (set-empty) v))))
(constructor sum () Term :cost 1000)
(union (sum) (Lam (V "xs") (CaseSplit (Var (V "xs")) (Num 0) (Lam (V "x") (Lam (V "xs'") (Add (Var (V "x")) (App (sum) (Var (V "xs'")))))))))
(set (freer (sum)) (set-empty))
(run 100)