///|
fn reverse_strength(
schema : Schema,
target : String,
values : Map[String, Value],
weak : Bool,
) -> Tri {
let mut strength = N
for source in schema.defs {
let source_value = values.get(source.name).unwrap_or(Logic(N)).logic()
let edges = if weak { source.implies } else { source.selects }
for (name, condition) in edges {
if name == target {
strength = strength.join(
source_value.meet(
condition.condition(
values,
schema.modules_enabled(values),
linux612=schema.linux612,
),
),
)
}
}
}
strength
}
///|
fn apply_reverse(
schema : Schema,
d : Definition,
kind : Kind,
base : Value,
reason : String,
requests : Map[String, Value],
values : Map[String, Value],
) -> (Value, String) {
if kind != Boolean && kind != Tristate {
return (base, reason)
}
let strong = reverse_strength(schema, d.name, values, false)
let weak = reverse_strength(schema, d.name, values, true)
let user = requests.contains(d.name) &&
direct_visibility(schema, d, kind, values) != N
let mut value = base.logic()
let mut why = reason
if !user &&
d.depends.condition(
values,
schema.modules_enabled(values),
linux612=schema.linux612,
) !=
N &&
weak.rank() > value.rank() {
value = if schema.linux612 {
weak.meet(
d.depends.condition(
values,
schema.modules_enabled(values),
linux612=true,
),
)
} else {
weak
}
why = "imply"
}
if strong.rank() > value.rank() {
value = strong
why = "select"
}
if value == M && (kind == Boolean || (!schema.linux612 && weak == Y)) {
value = Y
}
(Logic(value), why)
}