///|
pub fn Lattice::find_intent(self : Lattice, intent : Array[Int32]) -> Int32? {
let intent = index_set(intent)
for i = 0; i < self.size(); i = i + 1 {
if self.nodes[i].intent == intent {
return Some(i)
}
}
None
}
///|
pub fn Lattice::find_extent(self : Lattice, extent : Array[Int32]) -> Int32? {
let extent = index_set(extent)
for i = 0; i < self.size(); i = i + 1 {
if self.nodes[i].extent == extent {
return Some(i)
}
}
None
}
///|
/// Greatest lower bound: intersection of closed extents.
pub fn Lattice::meet(
self : Lattice,
left : Int32,
right : Int32,
) -> Int32 raise FcaError {
self.check_node(left)
self.check_node(right)
match
self.find_extent(
set_intersection(self.nodes[left].extent, self.nodes[right].extent),
) {
Some(index) => index
None => raise Invalid("internal lattice invariant: meet missing")
}
}
///|
/// Least upper bound: intersection of closed intents (reverse inclusion).
pub fn Lattice::join(
self : Lattice,
left : Int32,
right : Int32,
) -> Int32 raise FcaError {
self.check_node(left)
self.check_node(right)
match
self.find_intent(
set_intersection(self.nodes[left].intent, self.nodes[right].intent),
) {
Some(index) => index
None => raise Invalid("internal lattice invariant: join missing")
}
}
///|
pub fn Lattice::top(self : Lattice) -> Int32 {
let mut top = 0
for i = 1; i < self.size(); i = i + 1 {
if self.order[top][i] {
top = i
}
}
top
}
///|
pub fn Lattice::bottom(self : Lattice) -> Int32 {
let mut bottom = 0
for i = 1; i < self.size(); i = i + 1 {
if self.order[i][bottom] {
bottom = i
}
}
bottom
}
///|
/// Empty meet is the top element.
pub fn Lattice::meet_all(
self : Lattice,
nodes : Array[Int32],
) -> Int32 raise FcaError {
let mut result = self.top()
for node in nodes {
result = self.meet(result, node)
}
result
}
///|
/// Empty join is the bottom element.
pub fn Lattice::join_all(
self : Lattice,
nodes : Array[Int32],
) -> Int32 raise FcaError {
let mut result = self.bottom()
for node in nodes {
result = self.join(result, node)
}
result
}
///|
pub fn Lattice::interval(
self : Lattice,
lower : Int32,
upper : Int32,
) -> Array[Int32] raise FcaError {
if !self.leq(lower, upper) {
raise Invalid("interval endpoints are not ordered")
}
let result : Array[Int32] = []
for i = 0; i < self.size(); i = i + 1 {
if self.order[lower][i] && self.order[i][upper] {
result.push(i)
}
}
result
}