aaias-library 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ Metadata-Version: 2.5
2
+ Name: aaias-library
3
+ Version: 0.1.0
4
+ Summary: A personal collection of AI algorithm code templates
5
+ License-Expression: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+
9
+ # AAIAS — AI Algorithm Source Library
10
+
11
+ AAIAS is a Python library that provides source-code templates for common Applied Artificial Intelligence algorithms. Retrieve the source code of an algorithm as text and inspect, copy, or adapt it for your projects.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install aaias-library
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ Import `get_template` and request the algorithm you want:
22
+
23
+ ```python
24
+ from aaias import get_template
25
+
26
+ source_code = get_template("bfs")
27
+ print(source_code)
28
+ ```
29
+
30
+ The function returns the algorithm's source code as a string. It does not automatically execute the algorithm.
31
+
32
+ ## Available Templates
33
+
34
+ | Template | Name |
35
+ |---|---|
36
+ | Breadth-First Search | `bfs` |
37
+ | Depth-First Search | `dfs` |
38
+ | Greedy Best-First Search | `gbfs` |
39
+ | AI Agents | `agents` |
40
+ | Model Checking | `model_checking` |
41
+ | Bayesian Belief Network | `bayes_belief_network` |
42
+
43
+ For example, to retrieve the Bayesian Belief Network template:
44
+
45
+ ```python
46
+ from aaias import get_template
47
+
48
+ print(get_template("bayes_belief_network"))
49
+ ```
50
+
51
+ ## Error Handling
52
+
53
+ If you request an unknown template, `get_template()` raises a `ValueError` listing the available template names.
54
+
55
+ ## License
56
+
57
+ MIT
@@ -0,0 +1,49 @@
1
+ # AAIAS — AI Algorithm Source Library
2
+
3
+ AAIAS is a Python library that provides source-code templates for common Applied Artificial Intelligence algorithms. Retrieve the source code of an algorithm as text and inspect, copy, or adapt it for your projects.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install aaias-library
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Import `get_template` and request the algorithm you want:
14
+
15
+ ```python
16
+ from aaias import get_template
17
+
18
+ source_code = get_template("bfs")
19
+ print(source_code)
20
+ ```
21
+
22
+ The function returns the algorithm's source code as a string. It does not automatically execute the algorithm.
23
+
24
+ ## Available Templates
25
+
26
+ | Template | Name |
27
+ |---|---|
28
+ | Breadth-First Search | `bfs` |
29
+ | Depth-First Search | `dfs` |
30
+ | Greedy Best-First Search | `gbfs` |
31
+ | AI Agents | `agents` |
32
+ | Model Checking | `model_checking` |
33
+ | Bayesian Belief Network | `bayes_belief_network` |
34
+
35
+ For example, to retrieve the Bayesian Belief Network template:
36
+
37
+ ```python
38
+ from aaias import get_template
39
+
40
+ print(get_template("bayes_belief_network"))
41
+ ```
42
+
43
+ ## Error Handling
44
+
45
+ If you request an unknown template, `get_template()` raises a `ValueError` listing the available template names.
46
+
47
+ ## License
48
+
49
+ MIT
@@ -0,0 +1,16 @@
1
+
2
+ [build-system]
3
+ requires = ["hatchling"]
4
+ build-backend = "hatchling.build"
5
+
6
+ [project]
7
+ name = "aaias-library"
8
+ version = "0.1.0"
9
+ description = "A personal collection of AI algorithm code templates"
10
+ readme = { file = "README.md", content-type = "text/markdown" }
11
+ requires-python = ">=3.10"
12
+ license = "MIT"
13
+
14
+ [tool.hatch.build.targets.wheel]
15
+ packages = ["src/aaias"]
16
+
@@ -0,0 +1,3 @@
1
+ from .loader import get_template
2
+
3
+ __all__ = ["get_template"]
@@ -0,0 +1,29 @@
1
+ graph = {
2
+ 'A': ['B', 'C'],
3
+ 'B': ['D', 'E'],
4
+ 'C': ['F', 'G'],
5
+ 'D': [],
6
+ 'E': ['Z'],
7
+ 'F': [],
8
+ 'G': [],
9
+ 'Z': []
10
+ }
11
+ #BFS
12
+ def bfs(start,goal):
13
+ queue = [[start]]
14
+ visited = []
15
+
16
+ while queue:
17
+ path = queue.pop(0)
18
+ node = path[-1]
19
+
20
+ if node == goal:
21
+ return path
22
+
23
+ if node not in visited:
24
+ visited.append(node)
25
+
26
+ for neighbour in graph[node]:
27
+ queue.append(path + [neighbour])
28
+
29
+ print("BFS PATH:", bfs('A','Z'))
@@ -0,0 +1,24 @@
1
+ from pathlib import Path
2
+
3
+ _TEMPLATE_DIR = Path(__file__).parent / "templates"
4
+
5
+ AVAILABLE_TEMPLATES = {
6
+ "bfs": "bfs.py",
7
+ "dfs": "dfs.py",
8
+ "gbfs": "gbfs.py",
9
+ "agents": "agents.py",
10
+ "model_checking": "model_checking.py",
11
+ "bayes_belief_network": "bayes_belief_network.py"
12
+ }
13
+
14
+
15
+ def get_template(name):
16
+ """Return the source code of an algorithm as text."""
17
+ if name not in AVAILABLE_TEMPLATES:
18
+ raise ValueError(
19
+ f"Unknown template: {name}. "
20
+ f"Available templates: {list(AVAILABLE_TEMPLATES)}"
21
+ )
22
+
23
+ template_path = _TEMPLATE_DIR / AVAILABLE_TEMPLATES[name]
24
+ return template_path.read_text(encoding="utf-8")
@@ -0,0 +1,25 @@
1
+ #LAB2 - Vaccume cleaner agent (4 roms)
2
+ rooms = {'A': 'Dirty', 'B': 'Dirty',
3
+ 'C': 'Dirty', 'D': 'Dirty'}
4
+
5
+ location = 'A'
6
+ order = ['A', 'B', 'C', 'D']
7
+
8
+ while 'Dirty' in rooms.values():
9
+ print("\nRooms:", rooms)
10
+ print("Agent Location:", location)
11
+
12
+ if rooms[location] == 'Dirty':
13
+ rooms[location] = 'Clean'
14
+ print("Action: Suck")
15
+
16
+ else:
17
+ i = order.index(location)
18
+ if i < 3:
19
+ location = order[i + 1]
20
+ print("Action: Move Right")
21
+ else:
22
+ break
23
+
24
+ print("\nGoal Achieved!")
25
+ print("Final Rooms:", rooms)
@@ -0,0 +1,255 @@
1
+
2
+ from pgmpy.models import DiscreteBayesianNetwork
3
+ from pgmpy.factors.discrete import TabularCPD
4
+ from pgmpy.inference import VariableElimination
5
+ import networkx as nx
6
+ import matplotlib.pyplot as plt
7
+ from itertools import product
8
+
9
+
10
+ # 1. Define the Bayesian Network
11
+ model = DiscreteBayesianNetwork([
12
+ ('B', 'A'),
13
+ ('E', 'A')
14
+ ])
15
+
16
+
17
+ # 2. Define the Conditional Probability Tables (CPTs)
18
+
19
+ # P(B): Burglary
20
+ cpd_b = TabularCPD(
21
+ variable='B',
22
+ variable_card=2,
23
+ values=[[0.99], [0.01]]
24
+ )
25
+
26
+ # P(E): Earthquake
27
+ cpd_e = TabularCPD(
28
+ variable='E',
29
+ variable_card=2,
30
+ values=[[0.98], [0.02]]
31
+ )
32
+
33
+ # P(A | B, E): Alarm
34
+ # Columns: (B=0,E=0), (B=0,E=1),
35
+ # (B=1,E=0), (B=1,E=1)
36
+ cpd_a = TabularCPD(
37
+ variable='A',
38
+ variable_card=2,
39
+ values=[
40
+ [0.999, 0.71, 0.06, 0.05],
41
+ [0.001, 0.29, 0.94, 0.95]
42
+ ],
43
+ evidence=['B', 'E'],
44
+ evidence_card=[2, 2]
45
+ )
46
+
47
+ model.add_cpds(cpd_b, cpd_e, cpd_a)
48
+
49
+ print("Model is valid:", model.check_model())
50
+
51
+
52
+ # 3. Display CPTs
53
+ for cpd in model.get_cpds():
54
+ print(f"\nCPT of {cpd.variable}:")
55
+ print(cpd)
56
+
57
+
58
+ # 4. Display adjacency matrix
59
+ nodes = sorted(model.nodes())
60
+ adj = nx.to_pandas_adjacency(
61
+ nx.DiGraph(model.edges()),
62
+ nodelist=nodes,
63
+ dtype=int
64
+ )
65
+ print("\nAdjacency matrix:")
66
+ print(adj)
67
+
68
+
69
+ # 5. Visualize the network
70
+ pos = {
71
+ 'B': (-1, 1),
72
+ 'E': (1, 1),
73
+ 'A': (0, 0)
74
+ }
75
+
76
+ nx.draw(
77
+ nx.DiGraph(model.edges()),
78
+ pos,
79
+ with_labels=True,
80
+ node_size=2200,
81
+ node_color='lightblue',
82
+ edgecolors='steelblue',
83
+ font_size=14,
84
+ font_weight='bold',
85
+ arrowsize=20
86
+ )
87
+ plt.title("Burglary-Earthquake-Alarm Network")
88
+ plt.show()
89
+
90
+
91
+ # 6. Exact inference
92
+ infer = VariableElimination(model)
93
+
94
+ print("\nP(A):")
95
+ print(infer.query(variables=['A'], show_progress=False))
96
+
97
+ print("\nP(A | B=1):")
98
+ print(infer.query(
99
+ variables=['A'],
100
+ evidence={'B': 1},
101
+ show_progress=False
102
+ ))
103
+
104
+ print("\nP(B | A=1):")
105
+ print(infer.query(
106
+ variables=['B'],
107
+ evidence={'A': 1},
108
+ show_progress=False
109
+ ))
110
+
111
+
112
+ # 7. Marginal probability of state 1
113
+ print("\nMarginal probabilities:")
114
+ for node in sorted(model.nodes()):
115
+ q = infer.query(variables=[node], show_progress=False)
116
+ print(f"P({node}=1) = {q.values[1]:.4f}")
117
+
118
+
119
+ # 8. Joint probability of a complete assignment
120
+ assignment = {'B': 1, 'E': 0, 'A': 1}
121
+
122
+ joint = 1.0
123
+ for cpd in model.get_cpds():
124
+ idx = (
125
+ [assignment[cpd.variable]]
126
+ + [assignment[e] for e in cpd.variables[1:]]
127
+ )
128
+ joint *= cpd.values[tuple(idx)]
129
+
130
+ print("\nP(B=1, E=0, A=1):", round(joint, 6))
131
+
132
+
133
+ # 9. MAP inference
134
+ print("\nMAP of B, E given A=1:")
135
+ print(infer.map_query(
136
+ variables=['B', 'E'],
137
+ evidence={'A': 1},
138
+ show_progress=False
139
+ ))
140
+
141
+
142
+ # 10. Conditional independence checks
143
+ print("\nIs B independent of E?",
144
+ not model.is_dconnected('B', 'E'))
145
+
146
+ print("Is B independent of E given A?",
147
+ not model.is_dconnected('B', 'E', observed=['A']))
148
+
149
+
150
+ # 11. Query helper
151
+ def prob(query):
152
+ """
153
+ Query format:
154
+ P(a)
155
+ P(a | b)
156
+ P(b | a, ~e)
157
+
158
+ Lowercase means state 1; ~ means state 0.
159
+ """
160
+ query = query.replace(" ", "")
161
+ body = query[2:-1]
162
+
163
+ left, _, right = body.partition("|")
164
+
165
+ def parse(part):
166
+ result = {}
167
+ for term in filter(None, part.split(",")):
168
+ variable = term.lstrip("~").upper()
169
+ result[variable] = 0 if term.startswith("~") else 1
170
+ return result
171
+
172
+ targets = parse(left)
173
+ evidence = parse(right)
174
+
175
+ result = infer.query(
176
+ variables=list(targets),
177
+ evidence=evidence or None,
178
+ joint=True,
179
+ show_progress=False
180
+ )
181
+
182
+ return result.get_value(**targets)
183
+
184
+
185
+ # 12. Brute-force probability enumeration
186
+ def joint_prob(assignment):
187
+ p = 1.0
188
+ for cpd in model.get_cpds():
189
+ idx = (
190
+ [assignment[cpd.variable]]
191
+ + [assignment[e] for e in cpd.variables[1:]]
192
+ )
193
+ p *= cpd.values[tuple(idx)]
194
+ return p
195
+
196
+
197
+ def prob_enum(targets, evidence):
198
+ nodes = list(model.nodes())
199
+ numerator = 0.0
200
+ denominator = 0.0
201
+
202
+ for values in product([0, 1], repeat=len(nodes)):
203
+ world = dict(zip(nodes, values))
204
+
205
+ if not all(world[k] == v for k, v in evidence.items()):
206
+ continue
207
+
208
+ p = joint_prob(world)
209
+ denominator += p
210
+
211
+ if all(world[k] == v for k, v in targets.items()):
212
+ numerator += p
213
+
214
+ if denominator == 0:
215
+ raise ValueError("Evidence has zero probability.")
216
+
217
+ return numerator / denominator
218
+
219
+
220
+ # 13. Compare inference methods
221
+ queries = [
222
+ "P(a)",
223
+ "P(a | b)",
224
+ "P(b | a)",
225
+ "P(b | a, e)",
226
+ "P(b | a, ~e)",
227
+ "P(b, e | a)"
228
+ ]
229
+
230
+ print("\nProbability comparison:")
231
+ print(f"{'Query':<20}{'pgmpy':>12}{'Enumeration':>15}")
232
+ print("-" * 47)
233
+
234
+ for query in queries:
235
+ body = query.replace(" ", "")[2:-1]
236
+ left, _, right = body.partition("|")
237
+
238
+ def parse(part):
239
+ return {
240
+ term.lstrip("~").upper():
241
+ 0 if term.startswith("~") else 1
242
+ for term in filter(None, part.split(","))
243
+ }
244
+
245
+ targets = parse(left)
246
+ evidence = parse(right)
247
+
248
+ exact = prob(query)
249
+ enumerated = prob_enum(targets, evidence)
250
+
251
+ print(f"{query:<20}{exact:>12.4f}{enumerated:>15.4f}")
252
+
253
+
254
+ print("\nCustom query:")
255
+ print("P(B=1 | A=1, E=0) =", prob("P(b | a, ~e)"))
@@ -0,0 +1,29 @@
1
+ graph = {
2
+ 'A': ['B', 'C'],
3
+ 'B': ['D', 'E'],
4
+ 'C': ['F', 'G'],
5
+ 'D': [],
6
+ 'E': ['Z'],
7
+ 'F': [],
8
+ 'G': [],
9
+ 'Z': []
10
+ }
11
+ #BFS
12
+ def bfs(start,goal):
13
+ queue = [[start]]
14
+ visited = []
15
+
16
+ while queue:
17
+ path = queue.pop(0)
18
+ node = path[-1]
19
+
20
+ if node == goal:
21
+ return path
22
+
23
+ if node not in visited:
24
+ visited.append(node)
25
+
26
+ for neighbour in graph[node]:
27
+ queue.append(path + [neighbour])
28
+
29
+ print("BFS PATH:", bfs('A','Z'))
@@ -0,0 +1,34 @@
1
+
2
+ graph = {
3
+ 'A': ['B', 'C'],
4
+ 'B': ['D', 'E'],
5
+ 'C': ['F', 'G'],
6
+ 'D': [],
7
+ 'E': ['Z'],
8
+ 'F': [],
9
+ 'G': [],
10
+ 'Z': []
11
+ }
12
+
13
+ # DFS
14
+ def dfs(start, goal):
15
+ stack = [[start]]
16
+ visited = []
17
+
18
+ while stack:
19
+ path = stack.pop()
20
+ node = path[-1]
21
+
22
+ if node == goal:
23
+ return path
24
+
25
+ if node not in visited:
26
+ visited.append(node)
27
+
28
+ for neighbour in reversed(graph[node]):
29
+ stack.append(path + [neighbour])
30
+
31
+ return None
32
+
33
+
34
+ print("DFS PATH:", dfs('A', 'Z'))
@@ -0,0 +1,31 @@
1
+ graph = {
2
+ 'A': ['B', 'C', 'D'],
3
+ 'B': ['E'],
4
+ 'C': [],
5
+ 'D': [],
6
+ 'E': ['Z'],
7
+ 'Z': []
8
+ }
9
+
10
+ h = {'A': 21, 'B': 14, 'C': 18, 'D': 18, 'E': 5, 'Z': 0}
11
+
12
+ def best_first(start,goal):
13
+ open_list = [(h[start],[start])]
14
+ closed = []
15
+
16
+ while open_list:
17
+ open_list.sort()
18
+ value,path = open_list.pop(0)
19
+ node = path[-1]
20
+
21
+ if node == goal:
22
+ return path
23
+
24
+ if node not in closed:
25
+ closed.append(node)
26
+
27
+ for neighbour in graph[node]:
28
+ if neighbour not in closed:
29
+ open_list.append((h[neighbour],path+[neighbour]))
30
+
31
+ print("Best First Search:",best_first('A','Z'))
@@ -0,0 +1,261 @@
1
+ #1 create base sentence class
2
+
3
+ class Sentence:
4
+
5
+ def evaluate(self, model):
6
+ raise NotImplementedError
7
+
8
+ def formula(self):
9
+ raise NotImplementedError
10
+
11
+ def symbols(self):
12
+ raise NotImplementedError
13
+
14
+ #2 create symbol class
15
+
16
+ class Symbol(Sentence):
17
+
18
+ def __init__(self, name):
19
+ self.name = name
20
+
21
+ def __eq__(self, other):
22
+ return isinstance(other, Symbol) and self.name == other.name
23
+
24
+ def evaluate(self, model):
25
+ return model[self.name]
26
+
27
+ def formula(self):
28
+ return self.name
29
+
30
+ def symbols(self):
31
+ return {self.name}
32
+
33
+ def __repr__(self):
34
+ return self.name
35
+
36
+ #3 Implement NOT
37
+
38
+ class Not(Sentence):
39
+
40
+ def __init__(self, operand):
41
+ self.operand = operand
42
+
43
+ def evaluate(self, model):
44
+ return not self.operand.evaluate(model)
45
+
46
+ def formula(self):
47
+ return "¬" + self.operand.formula()
48
+
49
+ def symbols(self):
50
+ return self.operand.symbols()
51
+
52
+ #implement AND
53
+
54
+ class And(Sentence):
55
+
56
+ def __init__(self, left, right):
57
+ self.left = left
58
+ self.right = right
59
+
60
+ def evaluate(self, model):
61
+ return self.left.evaluate(model) and self.right.evaluate(model)
62
+
63
+ def formula(self):
64
+ return f"({self.left.formula()} ∧ {self.right.formula()})"
65
+
66
+ def symbols(self):
67
+ return self.left.symbols() | self.right.symbols()
68
+
69
+ #implement OR
70
+
71
+ class Or(Sentence):
72
+
73
+ def __init__(self, left, right):
74
+ self.left = left
75
+ self.right = right
76
+
77
+ def evaluate(self, model):
78
+ return self.left.evaluate(model) or self.right.evaluate(model)
79
+
80
+ def formula(self):
81
+ return f"({self.left.formula()} ∨ {self.right.formula()})"
82
+
83
+ def symbols(self):
84
+ return self.left.symbols() | self.right.symbols()
85
+
86
+ #implement implication
87
+
88
+ class Implication(Sentence):
89
+
90
+ def __init__(self, antecedent, consequent):
91
+ self.antecedent = antecedent
92
+ self.consequent = consequent
93
+
94
+ def evaluate(self, model):
95
+ return not (self.antecedent.evaluate(model) and not self.consequent.evaluate(model))
96
+
97
+ def formula(self):
98
+ return f"({self.antecedent.formula()} → {self.consequent.formula()})"
99
+
100
+ def symbols(self):
101
+ return self.antecedent.symbols() | self.consequent.symbols()
102
+
103
+
104
+ #implement biconditional
105
+
106
+ class Biconditional(Sentence):
107
+
108
+ def __init__(self, left, right):
109
+ self.left = left
110
+ self.right = right
111
+
112
+ def evaluate(self, model):
113
+ return self.left.evaluate(model) == self.right.evaluate(model)
114
+
115
+ def formula(self):
116
+ return f"({self.left.formula()} ↔ {self.right.formula()})"
117
+
118
+ def symbols(self):
119
+ return self.left.symbols() | self.right.symbols()
120
+
121
+ #create propositions
122
+
123
+ P = Symbol("P")
124
+ Q = Symbol("Q")
125
+ R = Symbol("R")
126
+
127
+ print(f"P: {P.formula()}")
128
+ print(f"Q: {Q.formula()}")
129
+ print(f"R: {R.formula()}")
130
+
131
+
132
+ model = {
133
+ "P": True,
134
+ "Q": False
135
+ }
136
+
137
+ print(f"P: {P.evaluate(model)}")
138
+ print(f"¬P: {Not(P).evaluate(model)}")
139
+ print(f"P ∧ Q: {And(P, Q).evaluate(model)}")
140
+ print(f"P ∨ Q: {Or(P, Q).evaluate(model)}")
141
+ print(f"P → Q: {Implication(P, Q).evaluate(model)}")
142
+ print(f"P ↔ Q: {Biconditional(P, Q).evaluate(model)}")
143
+
144
+ #implement model checking
145
+
146
+ def model_check(knowledge, query):
147
+
148
+ def check_all(knowledge, query, symbols, model):
149
+
150
+ if not symbols:
151
+ if knowledge.evaluate(model):
152
+ return query.evaluate(model)
153
+ return True
154
+
155
+ remaining_symbols = list(symbols)
156
+ p = remaining_symbols[0]
157
+ rest_symbols = set(remaining_symbols[1:])
158
+
159
+ model_true = model.copy()
160
+ model_true[p] = True
161
+
162
+ model_false = model.copy()
163
+ model_false[p] = False
164
+
165
+ return check_all(knowledge, query, rest_symbols, model_true) and \
166
+ check_all(knowledge, query, rest_symbols, model_false)
167
+
168
+ all_symbols = knowledge.symbols() | query.symbols()
169
+
170
+ return check_all(knowledge, query, all_symbols, {})
171
+
172
+ #p --> q , query q
173
+
174
+ kb = Implication(P, Q)
175
+
176
+ query = Q
177
+
178
+ result = model_check(kb, query)
179
+
180
+ print(f"Knowledge Base: {kb.formula()}")
181
+ print(f"Query: {query.formula()}")
182
+ print(f"Does the Knowledge Base entail the Query? {result}")
183
+
184
+ #(p-->q) ^ p , query q
185
+
186
+ kb = And(Implication(P, Q), P)
187
+
188
+ query = Q
189
+
190
+ result = model_check(kb, query)
191
+
192
+ print(f"Knowledge Base: {kb.formula()}")
193
+ print(f"Query: {query.formula()}")
194
+ print(f"Does the Knowledge Base entail the Query? {result}")
195
+
196
+ #(P ∨ Q) ∧ ¬P , query q
197
+
198
+ kb = And(Or(P, Q), Not(P))
199
+
200
+ query = Q
201
+
202
+ result = model_check(kb, query)
203
+
204
+ print(f"Knowledge Base: {kb.formula()}")
205
+ print(f"Query: {query.formula()}")
206
+ print(f"Does the Knowledge Base entail the Query? {result}")
207
+
208
+ #P ↔ Q , query p
209
+
210
+ kb = Biconditional(P, Q)
211
+
212
+ query = P
213
+
214
+ result = model_check(kb, query)
215
+
216
+ print(f"Knowledge Base: {kb.formula()}")
217
+ print(f"Query: {query.formula()}")
218
+ print(f"Does the Knowledge Base entail the Query? {result}")
219
+
220
+ #(P → Q) ∧ (Q → R) ∧ P , query:R
221
+
222
+ k_pq = Implication(P, Q)
223
+ k_qr = Implication(Q, R)
224
+ kb = And(And(k_pq, k_qr), P)
225
+
226
+ query = R
227
+
228
+ result = model_check(kb, query)
229
+
230
+ print(f"Knowledge Base: {kb.formula()}")
231
+ print(f"Query: {query.formula()}")
232
+ print(f"Does the Knowledge Base entail the Query? {result}")
233
+
234
+ #(P → Q) ∧ (Q → R), query :R
235
+ k_pq = Implication(P, Q)
236
+ k_qr = Implication(Q, R)
237
+ kb = And(k_pq, k_qr)
238
+
239
+ query = R
240
+
241
+ result = model_check(kb, query)
242
+
243
+ print(f"Knowledge Base: {kb.formula()}")
244
+ print(f"Query: {query.formula()}")
245
+ print(f"Does the Knowledge Base entail the Query? {result}")
246
+
247
+ #create own knowledge base
248
+ P = Symbol("P")
249
+ Q = Symbol("Q")
250
+ R = Symbol("R")
251
+
252
+ kb = And(
253
+ Implication(P, Q),
254
+ And(P, R)
255
+ )
256
+
257
+ query = Q
258
+
259
+ result = model_check(kb, query)
260
+
261
+ print(result)