temp
This commit is contained in:
commit
2e061e32bd
|
@ -0,0 +1 @@
|
|||
/target
|
|
@ -0,0 +1,25 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||
|
||||
[[package]]
|
||||
name = "finset-lattice-experiments"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "finset-lattice-experiments"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
itertools = "0.12.0"
|
|
@ -0,0 +1,286 @@
|
|||
use std::{fmt::Display, iter::repeat};
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
enum IncrementResult {
|
||||
Overflow,
|
||||
Good,
|
||||
}
|
||||
use IncrementResult::*;
|
||||
|
||||
trait Incrementable {
|
||||
fn increment(&mut self) -> IncrementResult;
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
struct Atom {
|
||||
smaller: Vec<bool>,
|
||||
}
|
||||
|
||||
impl Incrementable for Atom {
|
||||
fn increment(&mut self) -> IncrementResult {
|
||||
for a in &mut self.smaller {
|
||||
*a = !*a;
|
||||
if *a {
|
||||
return Good;
|
||||
}
|
||||
}
|
||||
return Overflow;
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct Lattice<I: Incrementable + Default> {
|
||||
order: Vec<I>,
|
||||
}
|
||||
|
||||
trait LatticeAbstract {
|
||||
fn le(&self, a: usize, b: usize) -> bool;
|
||||
fn grow(&mut self);
|
||||
}
|
||||
|
||||
impl Display for Lattice<Atom> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for (i, atom) in self.order.iter().enumerate() {
|
||||
let s = atom
|
||||
.smaller
|
||||
.iter()
|
||||
.map(|&b| if b { "1 " } else { "0 " })
|
||||
.collect::<String>();
|
||||
writeln!(f, "{}: {}", i, s)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Incrementable + Default> Incrementable for Lattice<I> {
|
||||
fn increment(&mut self) -> IncrementResult {
|
||||
for atom in &mut self.order {
|
||||
if let Good = atom.increment() {
|
||||
return Good;
|
||||
}
|
||||
}
|
||||
return Overflow;
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Incrementable> Lattice<I>
|
||||
where
|
||||
Self: LatticeAbstract,
|
||||
{
|
||||
fn next_lattice(&mut self) {
|
||||
self.increment();
|
||||
while !self.is_lattice() {
|
||||
if let Overflow = self.increment() {
|
||||
self.grow();
|
||||
}
|
||||
}
|
||||
}
|
||||
fn ge(&self, a: usize, b: usize) -> bool {
|
||||
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
|
||||
where
|
||||
C: Iterator<Item = usize>,
|
||||
F: Fn(&Self, usize, usize) -> bool,
|
||||
{
|
||||
let mut bound: Option<usize> = None;
|
||||
for new_bound in bound_candidates {
|
||||
let is_bound = || subset.iter().all(|&el| rel(self, el, new_bound));
|
||||
if let Some(old_bound) = bound {
|
||||
if rel(self, old_bound, new_bound) {
|
||||
continue;
|
||||
} else if rel(self, new_bound, old_bound) {
|
||||
panic!("Bound candidates must be sorted topologically");
|
||||
} else if is_bound() {
|
||||
return false;
|
||||
}
|
||||
} else if is_bound() {
|
||||
bound = Some(new_bound);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn is_lattice(&self) -> bool {
|
||||
if !self.is_transitive() {
|
||||
return false;
|
||||
}
|
||||
// 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
|
||||
// Possible optimization: a lack of LUB might imply no GLB so may only need to check one of them
|
||||
let mut subsets = (0..self.order.len()).powerset();
|
||||
subsets.next(); // Skip the empty set
|
||||
for subset in subsets {
|
||||
if !self.is_bounded(&subset, 0..self.order.len(), Lattice::le) {
|
||||
return false;
|
||||
}
|
||||
if !self.is_bounded(&subset, (0..self.order.len()).rev(), Lattice::ge) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
impl LatticeAbstract for Lattice<Atom> {
|
||||
fn le(&self, a: usize, b: usize) -> bool {
|
||||
if a == b {
|
||||
return true;
|
||||
}
|
||||
if a > b {
|
||||
return false;
|
||||
}
|
||||
if self.order[b].smaller[a] {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
fn grow(&mut self) {
|
||||
self.order = vec![Default::default(); self.order.len() + 1];
|
||||
for (i, atom) in self.order.iter_mut().enumerate() {
|
||||
*atom = Atom {
|
||||
smaller: vec![false; i],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut lattice = Lattice::default();
|
||||
for (i, _) in repeat(0).enumerate() {
|
||||
print!("{}", lattice);
|
||||
println!("iteration {}", i);
|
||||
lattice.next_lattice();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::error::Error;
|
||||
|
||||
#[test]
|
||||
fn test_is_lattice() -> Result<(), Box<dyn Error>> {
|
||||
let lattice = Lattice {
|
||||
order: vec![
|
||||
Atom { smaller: vec![] },
|
||||
Atom {
|
||||
smaller: vec![true],
|
||||
},
|
||||
Atom {
|
||||
smaller: vec![true, false],
|
||||
},
|
||||
],
|
||||
};
|
||||
assert!(lattice.is_lattice());
|
||||
let lattice = Lattice {
|
||||
order: vec![
|
||||
Atom { smaller: vec![] },
|
||||
Atom {
|
||||
smaller: vec![false],
|
||||
},
|
||||
Atom {
|
||||
smaller: vec![true, true],
|
||||
},
|
||||
],
|
||||
};
|
||||
assert!(lattice.is_lattice());
|
||||
Ok(())
|
||||
}
|
||||
#[test]
|
||||
fn test_is_not_lattice() -> Result<(), Box<dyn Error>> {
|
||||
let lattice = Lattice {
|
||||
order: vec![
|
||||
Atom { smaller: vec![] },
|
||||
Atom {
|
||||
smaller: vec![true],
|
||||
},
|
||||
Atom {
|
||||
smaller: vec![false, true],
|
||||
},
|
||||
],
|
||||
};
|
||||
assert!(!lattice.is_transitive());
|
||||
let lattice = Lattice {
|
||||
order: vec![
|
||||
Atom { smaller: vec![] },
|
||||
Atom {
|
||||
smaller: vec![false],
|
||||
},
|
||||
Atom {
|
||||
smaller: vec![true, true],
|
||||
},
|
||||
Atom {
|
||||
smaller: vec![true, true, false],
|
||||
},
|
||||
],
|
||||
};
|
||||
assert!(lattice.is_transitive());
|
||||
assert!(!lattice.is_lattice());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// 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> {
|
||||
// fn new(lattice: &'a Lattice) -> Self {
|
||||
// Operator {
|
||||
// lattice,
|
||||
// top: vec![false; lattice.order.len()],
|
||||
// ul: vec![false; lattice.order.len()],
|
||||
// ur: vec![false; lattice.order.len()],
|
||||
// dl: vec![false; lattice.order.len()],
|
||||
// dr: vec![false; lattice.order.len()],
|
||||
// bot: vec![false; lattice.order.len()],
|
||||
// }
|
||||
// }
|
||||
// fn increment(&mut self) {
|
||||
// let mut data = [
|
||||
// &mut self.bot,
|
||||
// &mut self.dr,
|
||||
// &mut self.dl,
|
||||
// &mut self.ur,
|
||||
// &mut self.ul,
|
||||
// &mut self.top,
|
||||
// ];
|
||||
// data[4][0] = false;
|
||||
// for (i, el) in data.iter_mut().enumerate() {
|
||||
// for a in el.iter_mut() {
|
||||
// *a = !*a;
|
||||
// if *a {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
Loading…
Reference in New Issue