help
This commit is contained in:
parent
2e061e32bd
commit
6b0d72c3a1
219
src/main.rs
219
src/main.rs
|
@ -12,14 +12,9 @@ trait Incrementable {
|
||||||
fn increment(&mut self) -> IncrementResult;
|
fn increment(&mut self) -> IncrementResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone)]
|
impl Incrementable for Vec<bool> {
|
||||||
struct Atom {
|
|
||||||
smaller: Vec<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Incrementable for Atom {
|
|
||||||
fn increment(&mut self) -> IncrementResult {
|
fn increment(&mut self) -> IncrementResult {
|
||||||
for a in &mut self.smaller {
|
for a in self {
|
||||||
*a = !*a;
|
*a = !*a;
|
||||||
if *a {
|
if *a {
|
||||||
return Good;
|
return Good;
|
||||||
|
@ -29,14 +24,38 @@ impl Incrementable for Atom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
struct Atom {
|
||||||
|
smaller: Vec<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Incrementable for Atom {
|
||||||
|
fn increment(&mut self) -> IncrementResult {
|
||||||
|
self.smaller.increment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone)]
|
||||||
|
struct AtomSet {
|
||||||
|
included: Vec<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Incrementable for AtomSet {
|
||||||
|
fn increment(&mut self) -> IncrementResult {
|
||||||
|
self.included.increment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct Lattice<I: Incrementable + Default> {
|
struct Lattice<I: Incrementable + Default, Ext = ()> {
|
||||||
|
ext: Ext,
|
||||||
order: Vec<I>,
|
order: Vec<I>,
|
||||||
}
|
}
|
||||||
|
|
||||||
trait LatticeAbstract {
|
trait LatticeAbstract {
|
||||||
fn le(&self, a: usize, b: usize) -> bool;
|
fn le(&self, a: usize, b: usize) -> bool;
|
||||||
fn grow(&mut self);
|
fn grow(&mut self) -> IncrementResult;
|
||||||
|
fn is_lattice(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Lattice<Atom> {
|
impl Display for Lattice<Atom> {
|
||||||
|
@ -64,41 +83,24 @@ impl<I: Incrementable + Default> Incrementable for Lattice<I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Incrementable> Lattice<I>
|
impl<I: Incrementable + Default> Lattice<I>
|
||||||
where
|
where
|
||||||
Self: LatticeAbstract,
|
Self: LatticeAbstract,
|
||||||
{
|
{
|
||||||
fn next_lattice(&mut self) {
|
fn next_lattice(&mut self) -> IncrementResult {
|
||||||
self.increment();
|
self.increment();
|
||||||
while !self.is_lattice() {
|
while !self.is_lattice() {
|
||||||
if let Overflow = self.increment() {
|
if let Overflow = self.increment() {
|
||||||
self.grow();
|
if let Overflow = self.grow() {
|
||||||
|
return Overflow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return Good;
|
||||||
}
|
}
|
||||||
fn ge(&self, a: usize, b: usize) -> bool {
|
fn ge(&self, a: usize, b: usize) -> bool {
|
||||||
return self.le(b, a);
|
return self.le(b, a);
|
||||||
}
|
}
|
||||||
// The underlying ordering might not be transitive, this makes it so
|
|
||||||
fn le_transitive(&self, a: usize, b: usize) -> bool {
|
|
||||||
if self.le(a, b) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (b, &active) in self.order[b].smaller.iter().enumerate() {
|
|
||||||
if active && self.le_transitive(a, b) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
fn is_transitive(&self) -> bool {
|
|
||||||
for (i, j) in (0..self.order.len()).cartesian_product(0..self.order.len()) {
|
|
||||||
if !self.le(i, j) && self.le_transitive(i, j) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
fn is_bounded<C, F>(&self, subset: &Vec<usize>, bound_candidates: C, rel: F) -> bool
|
fn is_bounded<C, F>(&self, subset: &Vec<usize>, bound_candidates: C, rel: F) -> bool
|
||||||
where
|
where
|
||||||
C: Iterator<Item = usize>,
|
C: Iterator<Item = usize>,
|
||||||
|
@ -122,10 +124,7 @@ where
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_lattice(&self) -> bool {
|
fn has_lub_glb(&self) -> bool {
|
||||||
if !self.is_transitive() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// A top/bottom element are inherent as are partial order conditions.
|
// A top/bottom element are inherent as are partial order conditions.
|
||||||
// Lattice condition can only fail if a set of elements have non comparable upper/lower bounds
|
// Lattice condition can only fail if a set of elements have non comparable upper/lower bounds
|
||||||
// Possible optimization: a lack of LUB might imply no GLB so may only need to check one of them
|
// Possible optimization: a lack of LUB might imply no GLB so may only need to check one of them
|
||||||
|
@ -141,6 +140,49 @@ where
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
fn monotone<Inc, Ext>(&self, other: &Lattice<Inc, Ext>) -> bool
|
||||||
|
where
|
||||||
|
Inc: Incrementable + Default,
|
||||||
|
Lattice<Inc, Ext>: LatticeAbstract,
|
||||||
|
{
|
||||||
|
assert_eq!(self.order.len(), other.order.len());
|
||||||
|
for (a, b) in (0..self.order.len()).cartesian_product((0..other.order.len())) {
|
||||||
|
if self.le(a, b) && !other.le(a, b) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
fn equal<Inc, Ext>(&self, other: &Lattice<Inc, Ext>) -> bool
|
||||||
|
where
|
||||||
|
Inc: Incrementable + Default,
|
||||||
|
Lattice<Inc, Ext>: LatticeAbstract,
|
||||||
|
{
|
||||||
|
self.monotone(other) && other.monotone(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Lattice<Atom> {
|
||||||
|
fn is_transitive(&self) -> bool {
|
||||||
|
for (i, j) in (0..self.order.len()).cartesian_product(0..self.order.len()) {
|
||||||
|
if !self.le(i, j) && self.le_transitive(i, j) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// The underlying ordering might not be transitive, this makes it so
|
||||||
|
fn le_transitive(&self, a: usize, b: usize) -> bool {
|
||||||
|
if self.le(a, b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (b, &active) in self.order[b].smaller.iter().enumerate() {
|
||||||
|
if active && self.le_transitive(a, b) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LatticeAbstract for Lattice<Atom> {
|
impl LatticeAbstract for Lattice<Atom> {
|
||||||
|
@ -156,13 +198,17 @@ impl LatticeAbstract for Lattice<Atom> {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
fn grow(&mut self) {
|
fn grow(&mut self) -> IncrementResult {
|
||||||
self.order = vec![Default::default(); self.order.len() + 1];
|
self.order = vec![Default::default(); self.order.len() + 1];
|
||||||
for (i, atom) in self.order.iter_mut().enumerate() {
|
for (i, atom) in self.order.iter_mut().enumerate() {
|
||||||
*atom = Atom {
|
*atom = Atom {
|
||||||
smaller: vec![false; i],
|
smaller: vec![false; i],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return Good;
|
||||||
|
}
|
||||||
|
fn is_lattice(&self) -> bool {
|
||||||
|
self.is_transitive() && self.has_lub_glb()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,6 +229,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_lattice() -> Result<(), Box<dyn Error>> {
|
fn test_is_lattice() -> Result<(), Box<dyn Error>> {
|
||||||
let lattice = Lattice {
|
let lattice = Lattice {
|
||||||
|
ext: (),
|
||||||
order: vec![
|
order: vec![
|
||||||
Atom { smaller: vec![] },
|
Atom { smaller: vec![] },
|
||||||
Atom {
|
Atom {
|
||||||
|
@ -195,6 +242,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
assert!(lattice.is_lattice());
|
assert!(lattice.is_lattice());
|
||||||
let lattice = Lattice {
|
let lattice = Lattice {
|
||||||
|
ext: (),
|
||||||
order: vec![
|
order: vec![
|
||||||
Atom { smaller: vec![] },
|
Atom { smaller: vec![] },
|
||||||
Atom {
|
Atom {
|
||||||
|
@ -211,6 +259,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_not_lattice() -> Result<(), Box<dyn Error>> {
|
fn test_is_not_lattice() -> Result<(), Box<dyn Error>> {
|
||||||
let lattice = Lattice {
|
let lattice = Lattice {
|
||||||
|
ext: (),
|
||||||
order: vec![
|
order: vec![
|
||||||
Atom { smaller: vec![] },
|
Atom { smaller: vec![] },
|
||||||
Atom {
|
Atom {
|
||||||
|
@ -223,6 +272,7 @@ mod tests {
|
||||||
};
|
};
|
||||||
assert!(!lattice.is_transitive());
|
assert!(!lattice.is_transitive());
|
||||||
let lattice = Lattice {
|
let lattice = Lattice {
|
||||||
|
ext: (),
|
||||||
order: vec![
|
order: vec![
|
||||||
Atom { smaller: vec![] },
|
Atom { smaller: vec![] },
|
||||||
Atom {
|
Atom {
|
||||||
|
@ -242,45 +292,58 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// struct Operator<'a> {
|
|
||||||
// lattice: &'a Lattice,
|
|
||||||
// top: Vec<bool>,
|
|
||||||
// ul: Vec<bool>,
|
|
||||||
// ur: Vec<bool>,
|
|
||||||
// dl: Vec<bool>,
|
|
||||||
// dr: Vec<bool>,
|
|
||||||
// bot: Vec<bool>,
|
|
||||||
// }
|
|
||||||
|
|
||||||
// impl<'a> Operator<'a> {
|
struct Mapping<'a> {
|
||||||
// fn new(lattice: &'a Lattice) -> Self {
|
domain: &'a Lattice<Atom>,
|
||||||
// Operator {
|
image: &'a Lattice<Atom>,
|
||||||
// lattice,
|
}
|
||||||
// top: vec![false; lattice.order.len()],
|
|
||||||
// ul: vec![false; lattice.order.len()],
|
// function: Lattice<AtomSet>,
|
||||||
// ur: vec![false; lattice.order.len()],
|
|
||||||
// dl: vec![false; lattice.order.len()],
|
type Operator<'a> = Lattice<AtomSet, Mapping<'a>>;
|
||||||
// dr: vec![false; lattice.order.len()],
|
|
||||||
// bot: vec![false; lattice.order.len()],
|
impl<'a> Operator<'a> {
|
||||||
// }
|
fn new(domain: &'a Lattice<Atom>, image: &'a Lattice<Atom>) -> Operator<'a> {
|
||||||
// }
|
Lattice {
|
||||||
// fn increment(&mut self) {
|
ext: Mapping { domain, image },
|
||||||
// let mut data = [
|
order: vec![AtomSet { included: vec![] }; image.order.len()],
|
||||||
// &mut self.bot,
|
}
|
||||||
// &mut self.dr,
|
}
|
||||||
// &mut self.dl,
|
fn all_nonempty(&self) -> bool {
|
||||||
// &mut self.ur,
|
self.order.iter().all(|set| set.included.iter().any(|&x| x))
|
||||||
// &mut self.ul,
|
}
|
||||||
// &mut self.top,
|
fn le_helper<I: Iterator<Item = usize> + Clone>(&self, a: I, b: I) -> bool {
|
||||||
// ];
|
b.clone()
|
||||||
// data[4][0] = false;
|
.all(|right| a.clone().any(|left| self.ext.domain.le(left, right)))
|
||||||
// for (i, el) in data.iter_mut().enumerate() {
|
}
|
||||||
// for a in el.iter_mut() {
|
}
|
||||||
// *a = !*a;
|
|
||||||
// if *a {
|
impl<'a> LatticeAbstract for Operator<'a> {
|
||||||
// return;
|
fn le(&self, a: usize, b: usize) -> bool {
|
||||||
// }
|
let pick = |which: usize| {
|
||||||
// }
|
self.order[which]
|
||||||
// }
|
.included
|
||||||
// }
|
.iter()
|
||||||
// }
|
.enumerate()
|
||||||
|
.filter_map(|(i, &included)| if included { Some(i) } else { None })
|
||||||
|
};
|
||||||
|
let left = pick(a);
|
||||||
|
let right = pick(b);
|
||||||
|
|
||||||
|
if !self.le_helper(left.clone(), right.clone()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if !self.le_helper(right, left) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn grow(&mut self) -> IncrementResult {
|
||||||
|
return Overflow;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_lattice(&self) -> bool {
|
||||||
|
self.all_nonempty() && self.ext.image.equal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue