 (defn intersect-intervals [i1 i2]
   (let [l1 (:left i1) r1 (:right i1) lo1 (:left-open i1) ro1 (:right-open i1)
 	l2 (:left i2) r2 (:right i2) lo2 (:left-open i2) ro2 (:right-open i2)]
-    (struct interval 
+    (make-interval 
 	    (max l1 l2)
 	    (cond (> l1 l2) lo1 (< l1 l2) lo2 :else (or lo1 lo2))
 	    (min r1 r2)

     (make-interval mid true       right right-open)]))








(ns edu.berkeley.ai.util.intervals
  (:use edu.berkeley.ai.util
	[clojure.contrib.types :only (deftype)]
        [clojure.contrib.generic :only (root-type)])
  (:require [clojure.contrib.generic.arithmetic :as ga]
            [clojure.contrib.generic.comparison :as gc]
            [clojure.contrib.generic.math-functions :as gm]))


(defstruct interval :left :left-open :right :right-open)

(deftype ::interval make-interval
  (fn [l lo r ro] (struct interval l lo r ro))
  (fn [i] (vals i)))

(derive ::interval root-type)


;(defn make-interval [left left-open right right-open]
;  (with-meta (struct interval left left-open right right-open)
;     {:type ::interval}))

(def *real-line* (make-interval Double/NEGATIVE_INFINITY true Double/POSITIVE_INFINITY true))

(defn make-point-interval [x] (make-interval x false x false))

(defn parse-interval 
  "Take a number, or [lb ub] expression where lb and ub can be nil, and produce
   an appropriate closed interval."
  [x] 
  (cond (number? x) (make-point-interval x)
	(nil? x) *real-line*
	(coll? x) (do (assert (<= (count x) 2))
		      (let [[l u] x]
			(make-interval (or l Double/NEGATIVE_INFINITY) (if l false true)
				       (or u Double/POSITIVE_INFINITY) (if u false true))))
	:else (throw (Exception. "I don't know how to make an interval out of " x))))

(defn interval-empty? [interval]
  (or (< (:right interval) (:left interval))
