mirror of
https://github.com/Brandon-Rozek/matmod.git
synced 2026-01-30 07:33:38 +00:00
Simplified satisfiable
This commit is contained in:
parent
6d87793803
commit
bf86bfd83e
1 changed files with 35 additions and 52 deletions
87
model.py
87
model.py
|
|
@ -5,7 +5,7 @@ a given logic.
|
||||||
from common import set_to_str, immutable
|
from common import set_to_str, immutable
|
||||||
from logic import (
|
from logic import (
|
||||||
get_propostional_variables, Logic,
|
get_propostional_variables, Logic,
|
||||||
Operation, PropositionalVariable, Term
|
Operation, PropositionalVariable, Rule, Term
|
||||||
)
|
)
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from functools import cached_property, lru_cache, reduce
|
from functools import cached_property, lru_cache, reduce
|
||||||
|
|
@ -277,67 +277,50 @@ def all_model_valuations_cached(
|
||||||
return list(all_model_valuations(pvars, mvalues))
|
return list(all_model_valuations(pvars, mvalues))
|
||||||
|
|
||||||
|
|
||||||
|
def rule_satisfied(
|
||||||
|
rule: Rule, valuations: List[Dict[PropositionalVariable, ModelValue]],
|
||||||
|
interpretation: Dict[Operation, ModelFunction], designated_values: Set[ModelValue]) -> bool:
|
||||||
|
"""
|
||||||
|
Checks whether a rule holds under all valuations listed in mapping.
|
||||||
|
|
||||||
|
If there is a mapping where the premise holds but the consequent does
|
||||||
|
not then this returns False.
|
||||||
|
"""
|
||||||
|
for valuation in valuations:
|
||||||
|
premise_met = True
|
||||||
|
for premise in rule.premises:
|
||||||
|
premise_t = evaluate_term(premise, valuation, interpretation)
|
||||||
|
if premise_t not in designated_values:
|
||||||
|
premise_met = False
|
||||||
|
break
|
||||||
|
|
||||||
|
# If any of the premises doesn't hold, then this won't serve as a counterexample
|
||||||
|
if not premise_met:
|
||||||
|
continue
|
||||||
|
|
||||||
|
consequent_t = evaluate_term(rule.conclusion, valuation, interpretation)
|
||||||
|
if consequent_t not in designated_values:
|
||||||
|
# Counterexample found, return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
# No mapping found which contradicts our rule
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def satisfiable(logic: Logic, model: Model, interpretation: Dict[Operation, ModelFunction]) -> bool:
|
def satisfiable(logic: Logic, model: Model, interpretation: Dict[Operation, ModelFunction]) -> bool:
|
||||||
"""
|
"""
|
||||||
Determine whether a model satisfies a logic
|
Determine whether a model satisfies a logic
|
||||||
given an interpretation.
|
given an interpretation.
|
||||||
"""
|
"""
|
||||||
pvars = tuple(get_propostional_variables(tuple(logic.rules)))
|
pvars = tuple(get_propostional_variables(tuple(logic.rules)))
|
||||||
mappings = all_model_valuations_cached(pvars, tuple(model.carrier_set))
|
valuations = all_model_valuations_cached(pvars, tuple(model.carrier_set))
|
||||||
|
|
||||||
for rule in logic.rules:
|
for rule in logic.rules:
|
||||||
# The rule most hold for all valuations
|
if not rule_satisfied(rule, valuations, interpretation, model.designated_values):
|
||||||
for mapping in mappings:
|
return False
|
||||||
# The check only applies if the premises are designated
|
|
||||||
premise_met = True
|
|
||||||
premise_ts: Set[ModelValue] = set()
|
|
||||||
|
|
||||||
for premise in rule.premises:
|
|
||||||
premise_t = evaluate_term(premise, mapping, interpretation)
|
|
||||||
# As soon as one premise is not designated,
|
|
||||||
# move to the next rule.
|
|
||||||
if premise_t not in model.designated_values:
|
|
||||||
premise_met = False
|
|
||||||
break
|
|
||||||
# If designated, keep track of the evaluated term
|
|
||||||
premise_ts.add(premise_t)
|
|
||||||
|
|
||||||
if not premise_met:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# With the premises designated, make sure the consequent is designated
|
|
||||||
consequent_t = evaluate_term(rule.conclusion, mapping, interpretation)
|
|
||||||
if consequent_t not in model.designated_values:
|
|
||||||
return False
|
|
||||||
|
|
||||||
for rule in logic.falsifies:
|
for rule in logic.falsifies:
|
||||||
# We must find one mapping where this does not hold
|
if rule_satisfied(rule, valuations, interpretation, model.designated_values):
|
||||||
counterexample_found = False
|
|
||||||
for mapping in mappings:
|
|
||||||
# The check only applies if the premises are designated
|
|
||||||
premise_met = True
|
|
||||||
premise_ts: Set[ModelValue] = set()
|
|
||||||
|
|
||||||
for premise in rule.premises:
|
|
||||||
premise_t = evaluate_term(premise, mapping, interpretation)
|
|
||||||
# As soon as one premise is not designated,
|
|
||||||
# move to the next rule.
|
|
||||||
if premise_t not in model.designated_values:
|
|
||||||
premise_met = False
|
|
||||||
break
|
|
||||||
# If designated, keep track of the evaluated term
|
|
||||||
premise_ts.add(premise_t)
|
|
||||||
|
|
||||||
if not premise_met:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# With the premises designated, make sure the consequent is not designated
|
|
||||||
consequent_t = evaluate_term(rule.conclusion, mapping, interpretation)
|
|
||||||
if consequent_t not in model.designated_values:
|
|
||||||
counterexample_found = True
|
|
||||||
break
|
|
||||||
|
|
||||||
if not counterexample_found:
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue