Boolean networks to Reaction Systems and Positive RS

This commit is contained in:
elvis
2025-12-22 00:58:45 +01:00
parent 478ca52816
commit 25dfe9147d
2 changed files with 195 additions and 29 deletions

View File

@ -774,6 +774,75 @@ impl System {
}
}
impl From<BooleanNetwork> for System {
fn from(value: BooleanNetwork) -> Self {
let reactions: Vec<Reaction> = {
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_r = vec![];
let mut partial_i = vec![];
let mut all_true = true;
let mut one_false = false;
for l in conjunctive {
match l {
| DNFLiteral::False => {
one_false = true;
all_true = false;
break;
},
| DNFLiteral::True => {},
| DNFLiteral::Variable { positive, variable } => {
if positive {
partial_r.push(variable);
} else {
partial_i.push(variable);
}
all_true = false;
},
}
}
if !one_false && !all_true {
res.push(Reaction::from(
Set::from(partial_r),
Set::from(partial_i),
Set::from([*el]),
));
} else if all_true {
res.push(Reaction::from(
Set::default(),
Set::default(),
Set::from([*el]),
));
}
}
}
res
};
Self::from(
Arc::new(Environment::default()),
Set::from_iter(
value
.initial_state
.iter()
.filter_map(
|(el, p)|
if *p { Some(*el) } else { None }
)
.collect::<Vec<_>>(),
),
Process::default(),
Arc::new(reactions),
)
}
}
// -----------------------------------------------------------------------------
// Statistics
// -----------------------------------------------------------------------------
@ -1103,30 +1172,27 @@ impl From<BooleanNetwork> for PositiveSystem {
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;
let mut all_true = true;
let mut one_false = false;
for l in conjunctive {
match l {
| DNFLiteral::False => {
one_false = true;
all_true = false;
break;
},
| DNFLiteral::True => {},
| DNFLiteral::Variable { positive, variable } => {
partial.push(PositiveType::from((
variable,
positive.into(),
)));
all_true = false;
},
}
}
if !all_true {
if !one_false && !all_true {
res.push(PositiveReaction::from(
PositiveSet::from(partial),
PositiveSet::from([PositiveType::from((
@ -1134,6 +1200,14 @@ impl From<BooleanNetwork> for PositiveSystem {
IdState::Positive,
))]),
));
} else if all_true {
res.push(PositiveReaction::from(
PositiveSet::default(),
PositiveSet::from([PositiveType::from((
*el,
IdState::Positive,
))]),
));
}
}
let bf_n =
@ -1142,30 +1216,27 @@ impl From<BooleanNetwork> for PositiveSystem {
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;
let mut all_true = true;
let mut one_false = false;
for l in conjunctive {
match l {
| DNFLiteral::False => {
one_false = true;
all_true = false;
break;
},
| DNFLiteral::True => {},
| DNFLiteral::Variable { positive, variable } => {
partial.push(PositiveType::from((
variable,
positive.into(),
)));
all_true = false;
},
}
}
if !all_true {
if !one_false && !all_true {
res.push(PositiveReaction::from(
PositiveSet::from(partial),
PositiveSet::from([PositiveType::from((
@ -1173,6 +1244,14 @@ impl From<BooleanNetwork> for PositiveSystem {
IdState::Negative,
))]),
));
} else if all_true {
res.push(PositiveReaction::from(
PositiveSet::default(),
PositiveSet::from([PositiveType::from((
*el,
IdState::Negative,
))]),
));
}
}
}

View File

@ -363,7 +363,7 @@ fn slice_trace_2() {
}
#[test]
fn from_boolean_positive() {
fn from_boolean_positive_1() {
let bn = BooleanNetwork {
initial_state: BTreeMap::from([(1, true), (2, true), (3, true)]),
update_rules: BTreeMap::from([
@ -390,3 +390,90 @@ fn from_boolean_positive() {
assert_eq!(rs.reaction_rules.len(), 8);
}
#[test]
fn from_boolean_positive_2() {
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::True),
Box::new(BooleanFunction::Variable(3)),
)),
),
),
(2, BooleanFunction::True),
(
3,
BooleanFunction::Not(Box::new(BooleanFunction::Variable(2))),
),
]),
};
let rs: PositiveSystem = bn.into();
assert_eq!(rs.reaction_rules.len(), 6);
}
#[test]
fn from_boolean_1() {
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: System = bn.into();
assert_eq!(rs.reaction_rules.len(), 4);
}
#[test]
fn from_boolean_2() {
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::True),
Box::new(BooleanFunction::Variable(3)),
)),
),
),
(2, BooleanFunction::True),
(
3,
BooleanFunction::Not(Box::new(BooleanFunction::Variable(2))),
),
]),
};
let rs: System = bn.into();
assert_eq!(rs.reaction_rules.len(), 4);
}