package scala.tools.nsc
package backend.icode
package analysis
trait SemiLattice {
  type Elem <: AnyRef
  
  final case class IState[V, S](vars: V, stack: S) {
    override def hashCode = vars.hashCode + stack.hashCode    
    override def equals(other: Any): Boolean = other match {
      case x: IState[_, _]  =>
        if ((this eq bottom) || (this eq top) || (x eq bottom) || (x eq top)) this eq x
        else stack == x.stack && vars == x.vars
      case _ =>
        false
    }
  }
  
  def lub2(exceptional: Boolean)(a: Elem, b: Elem): Elem
  
  def top: Elem
  
  def bottom: Elem
  
  def lub(xs: List[Elem], exceptional: Boolean): Elem = 
    if (xs.isEmpty) bottom
    else try xs reduceLeft lub2(exceptional)
    catch { case e: LubException  => Console.println("Lub on blocks: " + xs) ; throw e }
}