-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelpers.py
76 lines (63 loc) · 2.13 KB
/
helpers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from re import match
from typing import List, Dict, Any
def parseLine(line):
temp = match(r"Rule\((\d+)\): IF \(([^)]+)\), THEN \(([^)]+)\)", line.decode("utf-8").strip())
if temp:
return {
"number": int(temp.group(1)),
"premises": [p.strip() for p in temp.group(2).split(',')],
"actions": [a.strip() for a in temp.group(3).split(',')]
}
return None
def filterRules(rules, facts):
return [rule for rule in rules if not all(action in facts for action in rule["actions"])]
def getFirstVerifiedRuleIndex(facts, rules):
for index, rule in enumerate(rules):
if all(premise in facts for premise in rule["premises"]):
return index
return None
def forwardChaining(facts, rules, factToProve):
fact_found: bool = factToProve in facts
proof: List[Dict[str, Any]] = []
while not fact_found:
index: int = getFirstVerifiedRuleIndex(facts, rules)
if index is None:
break
else:
rule: Dict[str, Any] = rules[index]
facts.extend(rule["actions"])
proof.append({
"rule" : rule,
"facts": facts.copy()
})
rules.remove(rule)
if(factToProve in rule["actions"]):
fact_found = True
return proof, fact_found
def backwardChaining(facts, rules: List[Dict[str, Any]], factToProve):
if(factToProve in facts):
return [], True
done = False
while not done:
rule: Dict[str, Any] = getNextRule(factToProve, rules)
if(rule is None):
return [], False
proofs = [{
"rule": rule,
}]
all_premises_proven = True
rules.remove(rule)
for premise in rule["premises"]:
premise_proof, premise_proven = backwardChaining(facts, rules, premise)
proofs.extend(premise_proof)
if not premise_proven:
all_premises_proven = False
break
if all_premises_proven:
return proofs, all_premises_proven
return [], False
def getNextRule(fact, rules):
for _, rule in enumerate(rules):
if fact in rule["actions"]:
return rule
return None