package domain

import com.microsoft.z3._

/**
  * Abstract domain for references.
  */
class ReferenceDomain(ctx: Context) extends AbstractDomain {

  override type Element = ArrayExpr

  private val stringSort: SeqSort = ctx.mkStringSort()
  private val stringSet: SetSort = ctx.mkSetSort(stringSort)

  override def sort: Sort = stringSet

  override def top: Element = ctx.mkFullSet(stringSort)

  override def bottom: Element = ctx.mkEmptySet(stringSort)

  override def meet(e1: Element, e2: Element): Element =
    ctx.mkSetIntersection(e1, e2)

  override def join(e1: Element, e2: Element): Element =
    ctx.mkSetUnion(e1, e2)

  override def approx(e1: Element, e2: Element): BoolExpr =
    ctx.mkSetSubset(
      e1,
      e2
    )

  def toElement(pp: String): Element =
    ctx.mkSetAdd(
      ctx.mkEmptySet(stringSort),
      ctx.mkString(pp)
    )

}
