package analysis

import com.microsoft.z3._
import domain.AbstractDomainsCollection

/**
  * Abstract object Z3 representation.
  */
class Z3Object(ctx: Context, domains: AbstractDomainsCollection) {

  private val constructor: Constructor =
    ctx.mkConstructor(
      "mk-object",
      "is-object",
      Array("name", "prim", "ref", "taint"),
      Array[Sort](
        ctx.mkStringSort(),
        ctx.mkArraySort(ctx.mkStringSort(), domains.primitiveDomain.sort),
        ctx.mkArraySort(ctx.mkStringSort(), domains.referenceDomain.sort),
        ctx.mkArraySort(ctx.mkStringSort(), domains.taintDomain.sort)
      ),
      Array(0, 0, 0, 0)
    )

  val sort: DatatypeSort =
    ctx.mkDatatypeSort(
      "Object",
      Array(
        constructor
      )
    )

  private val accessors = constructor.getAccessorDecls

  val nameAccessor: FuncDecl = accessors(0)
  val primAccessor: FuncDecl = accessors(1)
  val refAccessor: FuncDecl = accessors(2)
  val taintAccessor: FuncDecl = accessors(3)
}
