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

models.util.ordering.als Maven / Gradle / Ivy

module util/ordering[exactly elem]

/*
 * Creates a single linear ordering over the atoms in elem. It also constrains all
 * the atoms to exist that are permitted by the scope on elem. That is, if the scope
 * on a signature S is 5, opening util/ordering[S] will force S to have 5 elements
 * and create a linear ordering over those five elements. The predicates and
 * functions below provide access to properties of the linear ordering, such as
 * which element is first in the ordering, or whether a given element precedes
 * another. You cannotcreate multiple linear orderings over the same signature with
 * this model. If you that functionality, try using the util/sequence module instead.
 *
 * Technical comment:
 * An important constraint: elem must contain all atoms permitted by the scope.
 * This is to let the analyzer optimize the analysis by setting all fields of each
 * instantiation of Ord to predefined values: e.g. by setting 'last' to the highest
 * atom of elem and by setting 'next' to {,,...}, where n is
 * the scope of elem. Without this constraint, it might not be true that Ord.last is
 * a subset of elem, and that the domain and range of Ord.next lie inside elem.
 *
 * author: Ilya Shlyakhter
 * revisions: Daniel jackson
 */

private one sig Ord {
   First: set elem,
   Next: elem -> elem
} {
   pred/totalOrder[elem,First,Next]
}

/** first */
fun first: one elem { Ord.First }

/** last */
fun last: one elem { elem - (next.elem) }

/** return a mapping from each element to its predecessor */
fun prev : elem->elem { ~(Ord.Next) }

/** return a mapping from each element to its successor */
fun next : elem->elem { Ord.Next }

/** return elements prior to e in the ordering */
fun prevs [e: elem]: set elem { e.^(~(Ord.Next)) }

/** return elements following e in the ordering */
fun nexts [e: elem]: set elem { e.^(Ord.Next) }

/** e1 is less than e2 in the ordering */
pred lt [e1, e2: elem] { e1 in prevs[e2] }

/** e1 is greater than e2 in the ordering */
pred gt [e1, e2: elem] { e1 in nexts[e2] }

/** e1 is less than or equal to e2 in the ordering */
pred lte [e1, e2: elem] { e1=e2 || lt [e1,e2] }

/** e1 is greater than or equal to e2 in the ordering */
pred gte [e1, e2: elem] { e1=e2 || gt [e1,e2] }

/** returns the larger of the two elements in the ordering */
fun larger [e1, e2: elem]: elem { lt[e1,e2] => e2 else e1 }

/** returns the smaller of the two elements in the ordering */
fun smaller [e1, e2: elem]: elem { lt[e1,e2] => e1 else e2 }

/**
 * returns the largest element in es
 * or the empty set if es is empty
 */
fun max [es: set elem]: lone elem { es - es.^(~(Ord.Next)) }

/**
 * returns the smallest element in es
 * or the empty set if es is empty
 */
fun min [es: set elem]: lone elem { es - es.^(Ord.Next) }

assert correct {
  let mynext = Ord.Next |
  let myprev = ~mynext | {
     ( all b:elem | (lone b.next) && (lone b.prev) && (b !in b.^mynext) )
     ( (no first.prev) && (no last.next) )
     ( all b:elem | (b!=first && b!=last) => (one b.prev && one b.next) )
     ( !one elem => (one first && one last && first!=last && one first.next && one last.prev) )
     ( one elem => (first=elem && last=elem && no myprev && no mynext) )
     ( myprev=~mynext )
     ( elem = first.*mynext )
     (all disj a,b:elem | a in b.^mynext or a in b.^myprev)
     (no disj a,b:elem | a in b.^mynext and a in b.^myprev)
     (all disj a,b,c:elem | (b in a.^mynext and c in b.^mynext) =>(c in a.^mynext))
     (all disj a,b,c:elem | (b in a.^myprev and c in b.^myprev) =>(c in a.^myprev))
  }
}
run {} for exactly 0 elem expect 0
run {} for exactly 1 elem expect 1
run {} for exactly 2 elem expect 1
run {} for exactly 3 elem expect 1
run {} for exactly 4 elem expect 1
check correct for exactly 0 elem
check correct for exactly 1 elem
check correct for exactly 2 elem
check correct for exactly 3 elem
check correct for exactly 4 elem
check correct for exactly 5 elem




© 2015 - 2025 Weber Informatics LLC | Privacy Policy