All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scroll.internal.formal.FormalConstraintModel.scala Maven / Gradle / Ivy

package scroll.internal.formal

/** Companion object for the formal representation of the constraint model.
  */
object FormalConstraintModel {

  def empty[NT >: Null <: AnyRef, RT >: Null <: AnyRef, CT >: Null <: AnyRef, RST >: Null <: AnyRef]
    : FormalConstraintModel[NT, RT, CT, RST] =
    FormalConstraintModel[NT, RT, CT, RST](Map.empty, Map.empty, List.empty)

  /** Little helper factory method for creating a constraint model with Strings only.
    */
  def forStrings(
    rolec: Map[String, List[((Int, Int), AnyRef)]],
    card: Map[String, ((Int, Int), (Int, Int))],
    intra: List[(String, List[(String, String)] => Boolean)]
  ): FormalConstraintModel[String, String, String, String] =
    FormalConstraintModel(rolec, card, intra)

}

/** Class representation of the Constraint Model.
  *
  * @param rolec
  *   the role constraints
  * @param card
  *   cardinality mappings
  * @param intra
  *   intra-relationship constraints
  * @tparam NT
  *   type of naturals
  * @tparam RT
  *   type of roles
  * @tparam CT
  *   type of compartments
  * @tparam RST
  *   type of relationships
  */
final case class FormalConstraintModel[
  NT >: Null <: AnyRef,
  RT >: Null <: AnyRef,
  CT >: Null <: AnyRef,
  RST >: Null <: AnyRef
](
  rolec: Map[CT, List[((Int, Int), AnyRef)]],
  card: Map[RST, ((Int, Int), (Int, Int))],
  intra: List[(RST, List[(NT, NT)] => Boolean)]
) {

  /** @param crom
    *   the CROM instance to check against
    * @return
    *   true iff the constraint model is compliant to the given CROM.
    */
  def compliant(crom: FormalCROM[NT, RT, CT, RST]): Boolean = crom.wellformed && axiom12(crom)

  def axiom12(crom: FormalCROM[NT, RT, CT, RST]): Boolean =
    FormalUtils.all(for {
      ct1    <- crom.ct if rolec.contains(ct1)
      (_, a) <- rolec(ct1)
    } yield FormalUtils.atoms(a).toSet.subsetOf(crom.parts(ct1).toSet))

  /** @param crom
    *   the CROM instance to check against
    * @param croi
    *   the CROI instance to check against
    * @return
    *   true iff the constraint model is compliant to the given CROM and the given CROI is valid wrt. the constraint
    *   model
    */
  def validity(crom: FormalCROM[NT, RT, CT, RST], croi: FormalCROI[NT, RT, CT, RST]): Boolean =
    compliant(crom) && croi.compliant(crom) && axiom13(crom, croi) && axiom14(croi) && axiom15(crom, croi) && axiom16(
      croi
    )

  def axiom13(crom: FormalCROM[NT, RT, CT, RST], croi: FormalCROI[NT, RT, CT, RST]): Boolean =
    FormalUtils.all(for {
      ct1      <- crom.ct if rolec.contains(ct1)
      (crd, a) <- rolec(ct1)
      c1       <- croi.c if croi.type1(c1) == ct1
    } yield {
      val sum = croi.o_c(c1).map(FormalUtils.evaluate(a, croi, _, c1)).sum
      crd._1 <= sum && sum <= crd._2
    })

  def axiom14(croi: FormalCROI[NT, RT, CT, RST]): Boolean =
    FormalUtils.all(for {
      (o, c, r) <- croi.plays if rolec.contains(croi.type1(c).asInstanceOf[CT])
      (_, a)    <- rolec(croi.type1(c).asInstanceOf[CT])
      if FormalUtils.atoms(a).contains(croi.type1(r))
    } yield FormalUtils.evaluate(a, croi, o, c) == 1)

  def axiom15(crom: FormalCROM[NT, RT, CT, RST], croi: FormalCROI[NT, RT, CT, RST]): Boolean =
    FormalUtils.all(for {
      rst        <- crom.rst if card.contains(rst)
      c          <- croi.c if croi.links.contains((rst, c))
      (r_1, r_2) <- croi.links((rst, c))
    } yield {
      val l1 = croi.pred(rst, c, r_2).size
      val l2 = croi.succ(rst, c, r_1).size
      card(rst)._1._1 <= l1 && l1 <= card(rst)._1._2 && card(rst)._2._1 <= l2 && l2 <= card(rst)._2._2
    })

  def axiom16(croi: FormalCROI[NT, RT, CT, RST]): Boolean =
    FormalUtils.all(for {
      c        <- croi.c
      (rst, f) <- intra if croi.links.contains((rst, c))
    } yield f(croi.overline_links(rst, c)))

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy