Boolean network to positive system

This commit is contained in:
elvis
2025-12-21 17:16:51 +01:00
parent 624446108e
commit 478ca52816
5 changed files with 180 additions and 83 deletions

View File

@ -38,7 +38,7 @@ impl BooleanFunction {
| Self::False => Self::True,
| Self::True => Self::False,
| Self::Not(bf) => bf.remove_literals(),
| _ => bf.remove_literals(),
| _ => Self::Not(Box::new(bf.remove_literals())),
},
| Self::Variable(i) => Self::Variable(*i),
| Self::And(bf1, bf2) => match (&**bf1, &**bf2) {
@ -524,8 +524,8 @@ impl DNFBooleanFunction {
#[derive(Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BooleanNetwork {
initial_state: BTreeMap<IdType, bool>,
update_rules: BTreeMap<IdType, BooleanFunction>,
pub initial_state: BTreeMap<IdType, bool>,
pub update_rules: BTreeMap<IdType, BooleanFunction>,
}
impl BooleanNetwork {

View File

@ -638,11 +638,11 @@ fn dnf_22() {
let correct_results = [
true, true, false, true, true, true, true, true, false, false, false,
false, false, false, false, false, true, true, false, true, true,
true, true, true, true, true, false, true, true, true, true, true,
true, true, false, true, true, true, true, true, true, true, false,
true, true, true, true, true, true, true, false, true, true, true,
true, true, true, true, false, true, true, true, true, true
false, false, false, false, false, true, true, false, true, true, true,
true, true, true, true, false, true, true, true, true, true, true,
true, false, true, true, true, true, true, true, true, false, true,
true, true, true, true, true, true, false, true, true, true, true,
true, true, true, false, true, true, true, true, true,
];
for (assignment, res) in assignments.iter().zip(correct_results) {
@ -655,8 +655,10 @@ fn dnf_23() {
let bf = boolean!(And((Or((Variable(0)), (Variable(1)))), (Variable(2))));
let cnf: DNFBooleanFunction = bf.into();
assert_eq!(cnf.formula, [vec![dnfl!(true, 0), dnfl!(true, 2)],
vec![dnfl!(true, 1), dnfl!(true, 2)]]);
assert_eq!(cnf.formula, [vec![dnfl!(true, 0), dnfl!(true, 2)], vec![
dnfl!(true, 1),
dnfl!(true, 2)
]]);
}
#[test]
@ -672,7 +674,9 @@ fn dnf_25() {
let bf = boolean!(Or((Variable(0)), (Or((Variable(1)), (Variable(2))))));
let cnf: DNFBooleanFunction = bf.into();
assert_eq!(cnf.formula, [[dnfl!(true, 0)],[dnfl!(true, 1)],[dnfl!(true, 2)]]);
assert_eq!(cnf.formula, [[dnfl!(true, 0)], [dnfl!(true, 1)], [dnfl!(
true, 2
)]]);
}
#[test]
@ -748,8 +752,10 @@ fn dnf_32() {
let bf = boolean!(Not(Or((Variable(0)), (Not(Or((True), (False)))))));
let cnf: DNFBooleanFunction = bf.into();
assert_eq!(cnf.formula, [[dnfl!(false, 0), dnfl!(True)],
[dnfl!(false, 0), dnfl!(False)]]);
assert_eq!(cnf.formula, [[dnfl!(false, 0), dnfl!(True)], [
dnfl!(false, 0),
dnfl!(False)
]]);
}
#[test]

View File

@ -59,6 +59,16 @@ impl std::ops::Not for IdState {
}
}
impl From<bool> for IdState {
fn from(value: bool) -> Self {
if value {
Self::Positive
} else {
Self::Negative
}
}
}
#[derive(
Clone,
Copy,

View File

@ -21,6 +21,10 @@ use super::set::{BasicSet, ExtensionsSet, PositiveSet, Set};
use super::trace::Trace;
use super::transitions::TransitionsIterator;
use super::translator::{Formatter, PrintableWithTranslator, Translator};
use crate::boolean::{
BooleanFunction, BooleanNetwork, DNFBooleanFunction, DNFLiteral,
};
use crate::element::PositiveType;
use crate::trace::{EnabledReactions, SlicingElement, SlicingTrace};
use crate::transitions::TraceIterator;
@ -1076,20 +1080,6 @@ impl From<System> for PositiveSystem {
let positive_entities =
value.available_entities.to_positive_set(IdState::Positive);
// let negative_entities = value
// .context_process
// .all_elements()
// .union(&value.environment().all_elements())
// .union(&value.reactions().iter().fold(
// Set::default(),
// |acc: Set, el| {
// acc.union(&el.inhibitors)
// .union(&el.products)
// .union(&el.reactants)
// },
// ))
// .subtraction(&value.available_entities)
// .to_positive_set(IdState::Negative);
let negative_entities =
value.products_elements().to_positive_set(IdState::Negative);
let new_available_entities =
@ -1103,6 +1093,116 @@ impl From<System> for PositiveSystem {
}
}
impl From<BooleanNetwork> for PositiveSystem {
fn from(value: BooleanNetwork) -> Self {
let reactions: Vec<PositiveReaction> = {
let mut res = vec![];
for (el, bf) in value.update_rules.iter() {
let bf_p = bf.remove_literals();
let dnf_p = DNFBooleanFunction::from(bf_p.clone());
for conjunctive in dnf_p.formula {
let mut partial = vec![];
let mut all_true = false;
for c in conjunctive {
match c {
| DNFLiteral::False => {},
| DNFLiteral::True => {
res.push(PositiveReaction::from(
PositiveSet::default(),
PositiveSet::from([PositiveType::from((
*el,
IdState::Positive,
))]),
));
all_true = true;
break;
},
| DNFLiteral::Variable { positive, variable } => {
partial.push(PositiveType::from((
variable,
positive.into(),
)));
},
}
}
if !all_true {
res.push(PositiveReaction::from(
PositiveSet::from(partial),
PositiveSet::from([PositiveType::from((
*el,
IdState::Positive,
))]),
));
}
}
let bf_n =
BooleanFunction::Not(Box::new(bf_p)).remove_literals();
let dnf_n = DNFBooleanFunction::from(bf_n);
for conjunctive in dnf_n.formula {
let mut partial = vec![];
let mut all_true = false;
for c in conjunctive {
match c {
| DNFLiteral::False => {},
| DNFLiteral::True => {
res.push(PositiveReaction::from(
PositiveSet::default(),
PositiveSet::from([PositiveType::from((
*el,
IdState::Negative,
))]),
));
all_true = true;
break;
},
| DNFLiteral::Variable { positive, variable } => {
partial.push(PositiveType::from((
variable,
positive.into(),
)));
},
}
}
if !all_true {
res.push(PositiveReaction::from(
PositiveSet::from(partial),
PositiveSet::from([PositiveType::from((
*el,
IdState::Negative,
))]),
));
}
}
}
res
};
Self::from(
Arc::new(PositiveEnvironment::default()),
PositiveSet::from_iter(
value
.initial_state
.iter()
.map(|el| {
(
*el.0,
if *el.1 {
IdState::Positive
} else {
IdState::Negative
},
)
})
.collect::<Vec<_>>(),
),
PositiveProcess::default(),
Arc::new(reactions),
)
}
}
impl PositiveSystem {
pub fn from(
delta: Arc<PositiveEnvironment>,

View File

@ -1,17 +1,16 @@
use std::collections::BTreeMap;
use std::sync::Arc;
use super::set::PositiveSet;
use super::system::BasicSystem;
use crate::system::ExtensionsSystem;
use super::element::{IdState, PositiveType};
use super::environment::{Environment, PositiveEnvironment};
use super::process::{PositiveProcess, Process};
use super::reaction::{PositiveReaction, Reaction};
use super::set::{BasicSet, PositiveSet, Set};
use super::system::{BasicSystem, ExtensionsSystem, PositiveSystem, System};
use crate::boolean::{BooleanFunction, BooleanNetwork};
#[test]
fn one_transition() {
use super::environment::Environment;
use super::process::Process;
use super::reaction::Reaction;
use super::set::{BasicSet, Set};
use super::system::{ExtensionsSystem, System};
let system = System::from(
Arc::new(Environment::default()),
Set::from([1, 2]),
@ -41,13 +40,6 @@ fn one_transition() {
#[test]
fn one_transition_2() {
use super::element::{IdState, PositiveType};
use super::environment::PositiveEnvironment;
use super::process::PositiveProcess;
use super::reaction::PositiveReaction;
use super::set::{BasicSet, PositiveSet};
use super::system::{ExtensionsSystem, PositiveSystem};
let system = PositiveSystem::from(
Arc::new(PositiveEnvironment::default()),
PositiveSet::from([
@ -117,12 +109,6 @@ fn one_transition_2() {
#[test]
fn convertion() {
use super::environment::Environment;
use super::process::Process;
use super::reaction::Reaction;
use super::set::{BasicSet, Set};
use super::system::{PositiveSystem, System};
let system = System::from(
Arc::new(Environment::default()),
Set::from([1, 2]),
@ -145,12 +131,6 @@ fn convertion() {
#[test]
fn traces_1() {
use super::environment::Environment;
use super::process::Process;
use super::reaction::Reaction;
use super::set::Set;
use super::system::{ExtensionsSystem, System};
let system = System::from(
Arc::new(Environment::from([
(100, Process::WaitEntity {
@ -231,12 +211,6 @@ fn traces_1() {
#[test]
fn traces_empty_env() {
use super::environment::Environment;
use super::process::Process;
use super::reaction::Reaction;
use super::set::Set;
use super::system::{ExtensionsSystem, System};
let system = System::from(
Arc::new(Environment::from([])),
Set::from([1, 2]),
@ -263,11 +237,6 @@ fn traces_empty_env() {
#[test]
fn conversion_reactions() {
use super::element::IdState::*;
use super::environment::Environment;
use super::process::Process;
use super::reaction::{PositiveReaction, Reaction};
use super::set::Set;
use super::system::{PositiveSystem, System};
let system = System::from(
Arc::new(Environment::from([])),
@ -305,11 +274,6 @@ fn conversion_reactions() {
#[test]
fn conversion_entities() {
use super::element::IdState::*;
use super::environment::Environment;
use super::process::Process;
use super::reaction::Reaction;
use super::set::Set;
use super::system::{PositiveSystem, System};
let system = System::from(
Arc::new(Environment::from([])),
@ -331,12 +295,6 @@ fn conversion_entities() {
#[test]
fn slice_trace() {
use super::environment::Environment;
use super::process::Process;
use super::reaction::Reaction;
use super::set::Set;
use super::system::{PositiveSystem, System};
let mut translator = crate::translator::Translator::new();
let mut tr = |a| translator.encode(a);
@ -368,12 +326,6 @@ fn slice_trace() {
#[test]
fn slice_trace_2() {
use super::environment::Environment;
use super::process::Process;
use super::reaction::Reaction;
use super::set::Set;
use super::system::{PositiveSystem, System};
let mut translator = crate::translator::Translator::new();
let mut tr = |a| translator.encode(a);
@ -409,3 +361,32 @@ fn slice_trace_2() {
assert_eq!(res_slice.systems, res_run);
}
#[test]
fn from_boolean_positive() {
let bn = BooleanNetwork {
initial_state: BTreeMap::from([(1, true), (2, true), (3, true)]),
update_rules: BTreeMap::from([
(
1,
BooleanFunction::Or(
Box::new(BooleanFunction::Not(Box::new(
BooleanFunction::Variable(1),
))),
Box::new(BooleanFunction::And(
Box::new(BooleanFunction::Variable(2)),
Box::new(BooleanFunction::Variable(3)),
)),
),
),
(2, BooleanFunction::Variable(3)),
(
3,
BooleanFunction::Not(Box::new(BooleanFunction::Variable(2))),
),
]),
};
let rs: PositiveSystem = bn.into();
assert_eq!(rs.reaction_rules.len(), 8);
}