     [expr]
     "Produce a `parsable` clojure expression from `expr`
  in optional lexical environement `env`."))
-            
+
+
+(defprotocol FreeVars
+  "A protocol for fetching the set of free variables."
+  (free-vars
+   [expr kind]
+   "Return a set of the free variables of `expr` according 
+to their kind: :product, :forall or :open."))
+
 ;;{
 ;;
 ;; ## Lambda-terms


(defn- match-product-var?
  [expr env]
  (match-bound-var? expr env 'forall))


(parser/register-term-other-parser
 match-product-var?
 (fn [expr env]
   (mk-product-var expr)))

(example (parse 'my-var (list ['my-var 'forall]))
         => (mk-product-var 'my-var))

(example (parse '(forall [x (univ 0)] x))

           rator (if (instance? Application (:rator app)) urator (list urator))
           urand (unparse (:rand app))
           rand (if (instance? Application (:rand app)) urand (list urand))]
       (append rator rand)))
  FreeVars
  (free-vars
      [app kind] (clojure.set/union (free-vars (:rator app) kind) (free-vars (:rand app) kind))))

(example (unparse (parse '((univ 1) (univ 2))))
         => '((univ 1) (univ 2)))
