mirror of
https://gitlab.kit.edu/uskyk/kv.git
synced 2024-11-25 02:15:06 +00:00
Better combinatoric implementation
This commit is contained in:
parent
56752a11d4
commit
2fc0445901
18
Cargo.lock
generated
18
Cargo.lock
generated
@ -1,5 +1,23 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kv"
|
name = "kv"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
|
dependencies = [
|
||||||
|
"itertools",
|
||||||
|
]
|
||||||
|
@ -7,3 +7,4 @@ edition = "2018"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
itertools = "0.10.0"
|
||||||
|
84
src/lib.rs
84
src/lib.rs
@ -1,3 +1,5 @@
|
|||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
pub type Variable = usize;
|
pub type Variable = usize;
|
||||||
|
|
||||||
pub const A: Variable = 1 << 0;
|
pub const A: Variable = 1 << 0;
|
||||||
@ -43,59 +45,43 @@ impl From<usize> for Output {
|
|||||||
|
|
||||||
pub type FunctionSpec = Vec<Output>;
|
pub type FunctionSpec = Vec<Output>;
|
||||||
|
|
||||||
pub fn find_groups(func: &FunctionSpec, vars: &mut [Variable], typ: Output) -> Vec<Vec<(Variable, Output)>> {
|
pub fn find_groups(func: &FunctionSpec, vars: &[Variable], typ: Output) -> Vec<Vec<(Variable, Output)>> {
|
||||||
find_recursive(func, vars, typ, vec![], 0, !0)
|
let mut groups: Vec<Vec<(Variable, Output)>> = Vec::new();
|
||||||
}
|
for k in 1..vars.len()+1 {
|
||||||
|
for vars in vars.iter().combinations(k) {
|
||||||
fn find_recursive(func: &FunctionSpec, vars: &mut [Variable], typ: Output, set: Vec<(Variable, Output)>, mask: Variable, inv_mask: Variable) -> Vec<Vec<(Variable, Output)>> {
|
for var_bits in 0..(1 << k) {
|
||||||
let mut groups = Vec::new();
|
let var_setting: Vec<_> = vars
|
||||||
for i in 0..vars.len() {
|
.iter()
|
||||||
let var = vars[i];
|
.enumerate()
|
||||||
if var == 0 {
|
.map(|(i, &&var)| (var, ((var_bits >> i) & 1).into()))
|
||||||
continue; // already set
|
.collect();
|
||||||
}
|
if groups.iter().any(|x| subset_of(x, &var_setting)) {
|
||||||
let mut fits_var_1 = true;
|
continue;
|
||||||
let mut fits_var_0 = true;
|
|
||||||
for input in 0..func.len() {
|
|
||||||
if !(input & inv_mask == input && input | mask == input) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if input & var != 0 {
|
|
||||||
if func[input] == typ.invert() {
|
|
||||||
fits_var_1 = false;
|
|
||||||
}
|
}
|
||||||
} else {
|
let mut mask = 0;
|
||||||
if func[input] == typ.invert() {
|
let mut inv_mask = !0;
|
||||||
fits_var_0 = false;
|
for (i, &&var) in vars.iter().enumerate() {
|
||||||
|
mask |= if ((var_bits >> i) & 1) == 1 { var } else { 0 };
|
||||||
|
inv_mask ^= if ((var_bits >> i) & 1) == 1 { 0 } else { var };
|
||||||
|
}
|
||||||
|
let mut fits = true;
|
||||||
|
for input in 0..func.len() {
|
||||||
|
if input | mask == input && input & inv_mask == input {
|
||||||
|
if func[input] == typ.invert() {
|
||||||
|
fits = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if fits {
|
||||||
|
groups.push(var_setting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !fits_var_0 && !fits_var_1 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if fits_var_1 {
|
|
||||||
let mut new_group = set.clone();
|
|
||||||
new_group.push((var, One));
|
|
||||||
groups.push(new_group);
|
|
||||||
} else {
|
|
||||||
let mut set2 = set.clone();
|
|
||||||
set2.push((var, One));
|
|
||||||
vars[i] = 0;
|
|
||||||
groups.extend(find_recursive(func, vars, typ, set2, mask | var, inv_mask));
|
|
||||||
vars[i] = var;
|
|
||||||
}
|
|
||||||
|
|
||||||
if fits_var_0 {
|
|
||||||
let mut new_group = set.clone();
|
|
||||||
new_group.push((var, Zero));
|
|
||||||
groups.push(new_group);
|
|
||||||
} else {
|
|
||||||
let mut set2 = set.clone();
|
|
||||||
set2.push((var, Zero));
|
|
||||||
vars[i] = 0;
|
|
||||||
groups.extend(find_recursive(func, vars, typ, set2, mask, inv_mask ^ var));
|
|
||||||
vars[i] = var;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
groups
|
groups
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn subset_of<T: Eq>(a: &[T], b: &[T]) -> bool {
|
||||||
|
a.iter().all(|x| b.contains(x))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user