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

View File

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

View File

@ -21,6 +21,10 @@ use super::set::{BasicSet, ExtensionsSet, PositiveSet, Set};
use super::trace::Trace; use super::trace::Trace;
use super::transitions::TransitionsIterator; use super::transitions::TransitionsIterator;
use super::translator::{Formatter, PrintableWithTranslator, Translator}; 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::trace::{EnabledReactions, SlicingElement, SlicingTrace};
use crate::transitions::TraceIterator; use crate::transitions::TraceIterator;
@ -1076,20 +1080,6 @@ impl From<System> for PositiveSystem {
let positive_entities = let positive_entities =
value.available_entities.to_positive_set(IdState::Positive); 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 = let negative_entities =
value.products_elements().to_positive_set(IdState::Negative); value.products_elements().to_positive_set(IdState::Negative);
let new_available_entities = 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 { impl PositiveSystem {
pub fn from( pub fn from(
delta: Arc<PositiveEnvironment>, delta: Arc<PositiveEnvironment>,

View File

@ -1,17 +1,16 @@
use std::collections::BTreeMap;
use std::sync::Arc; use std::sync::Arc;
use super::set::PositiveSet; use super::element::{IdState, PositiveType};
use super::system::BasicSystem; use super::environment::{Environment, PositiveEnvironment};
use crate::system::ExtensionsSystem; 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] #[test]
fn one_transition() { 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( let system = System::from(
Arc::new(Environment::default()), Arc::new(Environment::default()),
Set::from([1, 2]), Set::from([1, 2]),
@ -41,13 +40,6 @@ fn one_transition() {
#[test] #[test]
fn one_transition_2() { 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( let system = PositiveSystem::from(
Arc::new(PositiveEnvironment::default()), Arc::new(PositiveEnvironment::default()),
PositiveSet::from([ PositiveSet::from([
@ -117,12 +109,6 @@ fn one_transition_2() {
#[test] #[test]
fn convertion() { 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( let system = System::from(
Arc::new(Environment::default()), Arc::new(Environment::default()),
Set::from([1, 2]), Set::from([1, 2]),
@ -145,12 +131,6 @@ fn convertion() {
#[test] #[test]
fn traces_1() { 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( let system = System::from(
Arc::new(Environment::from([ Arc::new(Environment::from([
(100, Process::WaitEntity { (100, Process::WaitEntity {
@ -231,12 +211,6 @@ fn traces_1() {
#[test] #[test]
fn traces_empty_env() { 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( let system = System::from(
Arc::new(Environment::from([])), Arc::new(Environment::from([])),
Set::from([1, 2]), Set::from([1, 2]),
@ -263,11 +237,6 @@ fn traces_empty_env() {
#[test] #[test]
fn conversion_reactions() { fn conversion_reactions() {
use super::element::IdState::*; 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( let system = System::from(
Arc::new(Environment::from([])), Arc::new(Environment::from([])),
@ -305,11 +274,6 @@ fn conversion_reactions() {
#[test] #[test]
fn conversion_entities() { fn conversion_entities() {
use super::element::IdState::*; 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( let system = System::from(
Arc::new(Environment::from([])), Arc::new(Environment::from([])),
@ -331,12 +295,6 @@ fn conversion_entities() {
#[test] #[test]
fn slice_trace() { 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 translator = crate::translator::Translator::new();
let mut tr = |a| translator.encode(a); let mut tr = |a| translator.encode(a);
@ -368,12 +326,6 @@ fn slice_trace() {
#[test] #[test]
fn slice_trace_2() { 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 translator = crate::translator::Translator::new();
let mut tr = |a| translator.encode(a); let mut tr = |a| translator.encode(a);
@ -409,3 +361,32 @@ fn slice_trace_2() {
assert_eq!(res_slice.systems, res_run); 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);
}