-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAATS.py
218 lines (179 loc) · 6.07 KB
/
AATS.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
'''FORMAL AATS'''
import operator
class State:
def __init__(self,
propositions):
self.propositions = propositions
class Action:
def __init__(self,
initial_states,
resulting_state,
utilities,
name):
self.initial_states = initial_states
self.resulting_state = resulting_state
self.utilities = utilities
self.name = name
class Agent:
def __init__(self,
actions,
values):
self.actions = actions
self.values = values
#### STATES
home_before_eating = State(
{"hungry": True} #dictionary with propositions (from Phi)
)
after_dinner_michelin = State(
{"hungry": False}
)
after_dinner_febo = State(
{"hungry": False}
)
after_dinner_homefood = State(
{"hungry": False}
)
# finite, non-empty set of states with the first item as initial state
Q = [home_before_eating,
after_dinner_michelin,
after_dinner_febo,
after_dinner_homefood]
#### ACTIONS
k_goes_to_michelin = Action(
[home_before_eating], # possible initial states
after_dinner_michelin, # following state
{"quality":0.8, "low_price":0.1}, # utilities associated with this action
"King orange goes to Michelin" # name of the action
)
k_goes_to_febo = Action(
[home_before_eating],
after_dinner_febo,
{"quality":0.2, "low_price":0.9},
"King orange goes to FEBO"
)
k_does_homefood = Action(
[home_before_eating],
after_dinner_homefood,
{"quality":0.7, "low_price":0.9},
"King Orange eats at home"
)
t_goes_to_michelin = Action(
[home_before_eating],
after_dinner_michelin,
{"quality":0.8, "low_price":0.1},
"Tokkie goes to Michelin"
)
t_goes_to_febo = Action(
[home_before_eating],
after_dinner_febo,
{"quality":0.2, "low_price":0.9},
"Tokkie goes to FEBO"
)
t_does_homefood = Action(
[home_before_eating],
after_dinner_homefood,
{"quality":0.5, "low_price":0.9},
"Tokkie eats at home"
)
# list of possible actions
ac = [k_goes_to_michelin, k_goes_to_febo, k_does_homefood, t_goes_to_michelin, t_goes_to_febo, t_does_homefood]
#### AGENTS
king_orange = Agent(
[k_goes_to_michelin, k_goes_to_febo, k_does_homefood], #list with actions agent can perform
{"quality":0.9, "low_price":0.1} #dictionary with values
)
tokkie = Agent(
[t_goes_to_michelin, t_goes_to_febo, t_does_homefood],
{"quality":0.3, "low_price":0.8}
)
# finite, non-empty set of agents
ag = [king_orange, tokkie]
valueset = ["quality", "low_price"]
# finite, non-empty set of atomic propositions (things like: hungry, home etc., these could both be true or false)
# Phi = [prop1, prop2, prop3]
phi = ["hungry"]
# will return the set of states from which every action in ActionSet may be executed
def rho(Action):
return Action.initial_states
# will return state that would result from JointAction in state State
def tau(State, Action):
if (State in Action.initial_states):
return Action.resulting_state
else:
print("Error: this action (" + Action + ") is not allowed from State ("+ State +")")
# will return the set of primitive propositions satisfied in each case
def pi(State):
return State.propositions
# returns the agent involved in this action
def get_involved_agent(Action):
for agent in ag:
if Action in agent.actions:
return agent
# valuation function with expected utility
def delta(Action):
involved_agent = get_involved_agent(Action)
values = involved_agent.values
utilities = Action.utilities
exp_ut = 0
for item in values:
exp_ut += utilities[item] * values[item]
return exp_ut
#stage 1 critical questions
def problem_formulation(Init_state,Resulting_state, Action, goal):
involved_agent = get_involved_agent(Action)
## CQ 2
if tau(Init_state, Action) != Resulting_state:
return False
## CQ 3
if not all(x in set(list(pi(Resulting_state).keys())) for x in set(list(goal.keys()))):
return False
for value in list(goal.keys()):
if goal.get(value) != pi(Resulting_state).get(value):
return False
## CQ12
if Init_state not in Q:
return False
## CQ13
if Action not in ac:
return False
## CQ14
if tau(Init_state, Action) not in Q:
return False
## CQ 15
if not all(x in set(valueset) for x in set(involved_agent.values.keys())):
return False
## CQ 16
for state in Q:
if all(x in set(list(pi(state).keys())) for x in set(list(goal.keys()))):
for value in list(goal.keys()):
if goal.get(value) != pi(state).get(value):
break
return True
return False
# stage2 epistemic reasoning
def epistemic_reasoning(Init_state, Action):
## CQ 1
if not Init_state == Q[0]:
return False
if not Init_state in rho(Action):
return False
return True
# function to choose action
def choose_action(Init_state, Agent, goal):
actions_agent = Agent.actions
possible_actions = []
# loop through all actions agent can perform
for action in actions_agent:
res_state = tau(Init_state, action)
# make sure they pass the critical questions
if problem_formulation(Init_state, res_state, action, goal):
if epistemic_reasoning(Init_state, action):
possible_actions.append(action)
action_value_dict = {}
# calculate expected utilities
for pos_action in possible_actions:
action_value_dict[pos_action.name] = delta(pos_action)
print("The possible actions with their values for this agent are:\t \n" + str(action_value_dict))
# return highest action
return max(action_value_dict.items(), key=operator.itemgetter(1))[0]
print("Action that is chosen for agent Tokkie who is hungry and home:\t \n" + str(choose_action(home_before_eating, tokkie, {"hungry":False})))