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.
- aaias_library-0.1.0/PKG-INFO +57 -0
- aaias_library-0.1.0/README.md +49 -0
- aaias_library-0.1.0/pyproject.toml +16 -0
- aaias_library-0.1.0/src/aaias/__init__.py +3 -0
- aaias_library-0.1.0/src/aaias/bfs.py +29 -0
- aaias_library-0.1.0/src/aaias/loader.py +24 -0
- aaias_library-0.1.0/src/aaias/templates/agents.py +25 -0
- aaias_library-0.1.0/src/aaias/templates/bayes_belief_network.py +255 -0
- aaias_library-0.1.0/src/aaias/templates/bfs.py +29 -0
- aaias_library-0.1.0/src/aaias/templates/dfs.py +34 -0
- aaias_library-0.1.0/src/aaias/templates/gbfs.py +31 -0
- aaias_library-0.1.0/src/aaias/templates/model_checking.py +261 -0
|
@@ -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,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)
|