Untitled

 avatar
unknown
plain_text
2 years ago
6.9 kB
2
Indexable
### FILL IN YOUR SOLUTION HERE
### (AND ADD MORE CELLS DIRECTLY BELOW THIS ONE)

# Your program should go in the variable `asp_program`.

# The dummy below is intended to remind you to use do/3 and truck_at/2,
# to make the printing machinery work nicely.

asp_program = f"#const t={num_time_steps}.\n"

asp_program+="""
possible_time(1..t).
{ time(T): possible_time(T) }.
:- not time(1).
:-possible_time(T), possible_time(T+1), not time(T), time(T+1).

max_time(MaxTime) :- MaxTime = #max {T:time(T)}.
"""

for node in nodes:
    asp_program+=f"node({node}).\n"

for edge in edges:
    asp_program+=f"edge({edge[0]}, {edge[1]}).\n"

for factory in factories:
    asp_program+=f"""
factory({factory['location']}).
packages_at_factory({factory['location']}, {factory['load']}).
"""

for delivery_point in delivery_points:
    asp_program+=f"""
delivery_point({delivery_point['location']}).
demand_at_delivery_point({delivery_point['location']}, {delivery_point['demand']}).
"""

for charging_point in charging_points:
    asp_program+=f"charging_point({charging_point['location']}).\n"

for id, truck in enumerate(trucks):
    asp_program+=f"""
truck({id}).
truck_at({id}, {truck['location']}).
truck_capacity({id}, {truck['capacity']}).
truck_load({id}, {truck['load']}).
truck_charge_capacity({id},{truck['charge capacity']}).
truck_charge_level({id}, {truck['charge level']}).
"""

asp_program += """

% Edges are undirected 
edge(X,Y) :- edge(Y,X).

% ---------------------- Actions -----------------------------------

action(move(Pos)) :- node(Pos).
action(load(Pos))   :- factory(Pos).
action(charge(Pos)) :- charging_point(Pos).
action(unload(Pos)) :- delivery_point(Pos).
action(wait).

% Generate all possible Actions for each truck at each time step
1 { do(T,Tr, A) : action(A) } 1 :- time(T), truck(Tr). 

% ---------------------- Init States-----------------------------------
state(1, truck_at(Tr,Pos)) :- truck_at(Tr, Pos).
state(1, truck_charge_level(TR,L)) :- truck_charge_level(TR,L).
state(1, truck_load(Tr,Load)) :- truck_load(Tr,Load).
state(1, packages_at_factory(Pos,Load)) :- packages_at_factory(Pos,Load).
state(1, demand_at_delivery_point(Pos,Demand)) :- demand_at_delivery_point(Pos,Demand).

% ---------------------- Truck Movement ---------------------------------
state(T+1,truck_at(Tr, Pos2)) :- do(T,Tr,move(Pos2)), state(T,truck_at(Tr, Pos1)), truck(Tr), node(Pos1), node(Pos2), edge(Pos1, Pos2). 
state(T+1,truck_at(Tr, Pos)) :- do(T,Tr,_), not do(T,Tr,move(_)), state(T,truck_at(Tr,Pos)), truck(Tr).  % Dont move if you dont move
state(T+1,truck_charge_level(Tr,ChargeLevel)) :- do(T,Tr,_), not do(T,Tr, charge(_)), not do(T,Tr, move(_)), state(T,truck_charge_level(Tr,ChargeLevel)), truck(Tr).
state(T+1,truck_charge_level(Tr, ChargeLevel - 1)) :-  do(T,Tr,move(Pos2)), state(T,truck_charge_level(Tr, ChargeLevel)), truck(Tr), state(T,truck_at(Tr, Pos1)), edge(Pos1, Pos2).
state(T+1,truck_charge_level(Tr,ChargeLevel+1)) :- do(T,Tr,charge(_)), state(T, truck_charge_level(Tr,ChargeLevel)), truck(Tr).


:- do(T, Tr, move(Pos2)), state(T,truck_at(Tr, Pos1)), node(Pos1), node(Pos2), not edge(Pos1, Pos2). %Can't move to non-adjacent node
:- state(T,truck_at(Tr1,Pos)), state(T,truck_at(Tr2,Pos)), Tr1 != Tr2, node(Pos), truck(Tr1), truck(Tr2). % No truck on same node
:- do(T,ID,charge(_)), state(T,truck_charge_level(Tr,ChargeLevel1)), truck_charge_capacity(Tr,ChargeLevel2), truck(Tr), ChargeLevel1 == ChargeLevel2.
:- do(T,Tr1,move(Pos2)), do(T,Tr2,move(Pos1)), state(T, truck_at(Tr1, Pos1)), state(T, truck_at(Tr2, Pos2)), truck(Tr1), truck(Tr2), edge(Pos1, Pos2). %Trucks cant move past each other
:- do(T,Tr,move(_)), state(T,truck_charge_level(Tr, ChargeLevel)), truck(Tr), ChargeLevel == 0. % Can't move with no battery
:- do(T,Tr,charge(Pos1)), state(T,truck_at(Tr,Pos2)), truck(Tr), Pos2 != Pos1. % Can't perform an action from somewhere if truck isn't there

% ----------------------- Package Unloading ------------------------

state(T+1, truck_load(Tr,Load-1)) :- state(T,truck_load(Tr,Load)), do(T,Tr,unload(_)).
state(T+1, truck_load(Tr,Load))   :- state(T,truck_load(Tr,Load)), do(T,Tr,move(_)).
state(T+1, truck_load(Tr,Load))   :- state(T,truck_load(Tr,Load)), do(T,Tr,wait).
state(T+1, truck_load(Tr,Load))   :- state(T,truck_load(Tr,Load)), do(T,Tr,charge(_)).
state(T+1, demand_at_delivery_point(Pos,Demand)) :- state(T,demand_at_delivery_point(Pos,Demand)), do(T,_,_) , not do(T,_,unload(Pos)), delivery_point(Pos).
state(T+1, demand_at_delivery_point(Pos,Demand-1)) :- state(T,demand_at_delivery_point(Pos,Demand)), do(T,_,unload(Pos)), delivery_point(Pos).
state(T+1, packages_at_factory(Pos,Load)) :-  state(T,packages_at_factory(Pos,Load)), do(T,_,_), not do(T,_,load(Pos)), factory(Pos).


:- do(T,Tr,unload(_)), state(T, truck_load(Tr,Load)), Load == 0. % Empty truck can't unload.
:- do(T,Tr,unload(_)), state(T,demand_at_delivery_point(Pos,Demand)), delivery_point(Pos), Demand == 0. % Can't unload at delivery point with no demand.
:- do(T,Tr,unload(Pos1)), state(T,truck_at(Tr,Pos2)), Pos2 != Pos1. % Can't perform an action from somewhere if truck isn't there

% ----------------------- Package Loading ------------------------
% If a package is loaded, factory load decreases
state(T+1,packages_at_factory(Pos,Load-1)) :- do(T,_ ,load(Pos)), state(T,packages_at_factory(Pos,Load)), factory(Pos).
% Truck load increases when loading
state(T+1,truck_load(Tr,Load+1)) :- do(T,Tr,load(_)),state(T,truck_load(Tr,Load)).

:- do(T,Tr,load(Pos)), state(T,packages_at_factory(Pos, FactoryLoad)), factory(Pos), FactoryLoad == 0. % Can't Load in a factory if factory has no packages.
:- do(T,Tr,load(_)), state(T,truck_load(Tr,Load)),truck_capacity(Tr, Capacity), Load == Capacity. % If truck is full, it cant load a package
:- do(T,Tr,load(Pos1))  , state(T,truck_at(Tr,Pos2)), Pos2 != Pos1. % Can't perform an action from somewhere if truck isn't there

% ----------------------- Goals ------------------------

all_trucks_charging(T) :- possible_time(T), state(T, truck_at(_, Pos)) : charging_point(Pos).
all_delivery_points_full(T) :- possible_time(T), state(T, demand_at_delivery_point(Pos, 0)) : delivery_point(Pos).
all_trucks_empty(T) :- possible_time(T), state(T, truck_load(Tr,0)) : truck(Tr).

%Setting goal to T-1 indicates that current actions will lead to a next state that has already reached the goal.
goal_reached(T-1) :-  state(T, _), all_trucks_charging(T), all_delivery_points_full(T), all_trucks_empty(T).

%We require that the goal is reached at the end
:- max_time(M), not goal_reached(M).
%Once the goal is reached, we stop the clock
:- max_time(M), goal_reached(T), time(T), T < M.

% ----------------------- Optimisation ------------------------

#minimize { 1,T : state(T, _) }. %Shortest sequence of states

% ----------------------- Visualisation ------------------------

#show do/3.
#show truck_at/2.
"""

print(asp_program)
Editor is loading...