Skip to content

Instantly share code, notes, and snippets.

@dariusf
Created July 4, 2018 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dariusf/e73292df675a9f63117d058c9b356b9b to your computer and use it in GitHub Desktop.
Save dariusf/e73292df675a9f63117d058c9b356b9b to your computer and use it in GitHub Desktop.
% clingo 5 version of https://gist.github.com/rndmcnlly/cc801233012df3cb0883
%#script (lua) function min(a,b) return math.min(a,b) end #end.
#script (python)
def min1(a,b):
return min(a,b)
#end.
%% Adam's minimal event calculus formalism:
%% - only true holds/happens are tracked
%% - all fluents are always inertial
%% - time is a totally ordered contiguous integer sequence
%% - events and fluents are self-contained terms
%% - T variables always come first for easy sorting
initiated(T,F) :- happens(T,E), initiates(T,E,F).
terminated(T,F) :- happens(T,E), terminates(T,E,F).
holds(T+1,F) :- time(T), holds(T,F), not terminated(T,F).
holds(T+1,F) :- time(T), happens(T,E), initiates(T,E,F).
%% static structures in the authored universe
% links between star systems form digraph
jumpgate(sol,eta_ravioli).
jumpgate(eta_ravioli,sol).
jumpgate(sol,corea).
% stars may have many planets, indexed by integer to simplify fluent
orbit(sol,1,earth).
orbit(sol,2,mars).
orbit(sol,3,belt).
orbit(sol,4,jupiter).
orbit(eta_ravioli,1,meatball_one).
orbit(eta_ravioli,2,cloud).
orbit(corea,1,ring).
% extract systems, orbital ids, and planet names form facts above
system(S) :- orbit(S,N,P).
orbital(N) :- orbit(S,N,P).
planet(P) :- orbit(S,N,P).
% named places the main character can be
location(surface(P)) :- planet(P).
location(orbit(P)) :- planet(P).
location(adrift(S)) :- system(S).
% a production/consumption network to support trade
produces(earth,surface,trinkets).
produces(earth,surface,water).
produces(jupiter,orbit,hydrogen).
produces(belt,orbit,rocks).
produces(mars,orbit,rustbuckets).
produces(meatball_one,surface,urnoxen).
transduces(meatball_one,surface,urnoxen,urnox_hides).
consumes(ring,surface,urnox_hides).
consumes(earth,surface,rustbuckets).
consumes(belt,orbit,hydrogen).
consumes(jupiter,orbit,rocks).
% extract commodities mentioned anywhere in authored network
commodity(C) :- produces(_,_,C).
commodity(C) :- consumes(_,_,C).
commodity(C) :- transduces(_,_,C,_).
commodity(C) :- transduces(_,_,_,C).
% non-commodity items
sells(belt,jumpdrive,3).
equipment(E) :- sells(_,E,_).
% instead of finely grained interstellar credits, track quantized wealth class
wealth_class(1..4).
wealth_max(WMax) :- WMax = 4. % wealth_class(W), WMax = #max { 1,W }. % calculate vs. hard-code
%% EC fluents
% Normally, I would write ...
% fluent(loc(L)) :- location(L).
% ..., but, because I know locations, commodities, and wealth classes use
% disjoint sets of identifiers, I use the raw identifiers as fluents instead of
% wrapping them. If locations and commodities were abstract elements identified
% only by integers, I'd have to wrap them to distinguish them later. Unwrapped
% fluents save a few keystrokes later on,
fluent(L) :- location(L).
fluent(C) :- commodity(C).
fluent(wealth(W)) :- wealth_class(W). % loose integers are scary
fluent(E) :- equipment(E).
% holds(1,jumpdrive) means "my ship has a jumpdrive installed at T=1"
%% EC events (just declaring a space of terms here, no trigger logic)
event(enter_orbit(N)) :- orbital(N).
event(leave_orbit).
event(shuttle).
event(jump(S)) :- system(S).
event(gather(C)) :- commodity(C).
event(trade(C)) :- commodity(C).
event(transduce(C)) :- commodity(C).
event(buy(E)) :- equipment(E).
%% Preconditions (not officially part of EC, but a common idiom nonetheless)
possible(T,enter_orbit(N)) :- holds(T,adrift(S)), orbit(S,N,_).
possible(T,leave_orbit) :- holds(T,orbit(P)).
possible(T,shuttle) :- holds(T,orbit(P)).
possible(T,shuttle) :- holds(T,surface(P)).
possible(T,jump(S2)) :- holds(T,jumpdrive), holds(T,adrift(S1)), jumpgate(S1,S2).
possible(T,gather(C)) :- holds(T,surface(P)), produces(P,surface,C).
possible(T,gather(C)) :- holds(T,orbit(P)), produces(P,orbit,C).
possible(T,trade(C)) :- holds(T,C), holds(T,surface(P)), consumes(P,surface,C).
possible(T,trade(C)) :- holds(T,C), holds(T,orbit(P)), consumes(P,orbit,C).
possible(T,transduce(C1)) :- holds(T,C1), holds(T,surface(P)), transduces(P,surface,C1,C2).
possible(T,buy(E)) :- holds(T,wealth(W)), holds(T,orbit(P)), sells(P,E,W).
%% EC initiates rules
initiates(T,enter_orbit(N),orbit(P)) :- holds(T,adrift(S)), orbit(S,N,P).
initiates(T,leave_orbit,adrift(S)) :- holds(T,orbit(P)), orbit(S,N,P).
initiates(T,shuttle,surface(P)) :- holds(T,orbit(P)).
initiates(T,shuttle,orbit(P)) :- holds(T,surface(P)).
initiates(T,jump(S2),adrift(S2)) :- time(T), jumpgate(S1,S2).
initiates(T,gather(C),C) :- time(T), event(gather(C)).
initiates(T,trade(C),wealth(@min1(WMax,W+1))) :- % had to invent Lua helper "min"
commodity(C),
holds(T,wealth(W)),
wealth_max(WMax).
initiates(T,transduce(C1),C2) :- holds(T,surface(P)), transduces(P,surface,C1,C2).
initiates(T,buy(E),E) :- time(T), event(buy(E)).
%% EC terminates rules
terminates(T,enter_orbit(N),adrift(S)) :- holds(T,adrift(S)), orbit(S,N,P).
terminates(T,leave_orbit,orbit(P)) :- holds(T,orbit(P)).
terminates(T,shuttle,orbit(P)) :- holds(T,orbit(P)).
terminates(T,shuttle,surface(P)) :- holds(T,surface(P)).
terminates(T,jump(S2),adrift(S1)) :- holds(T,adrift(S1)), jumpgate(S1,S2).
% gather(C) doesn't termiante anything
terminates(T,trade(C),wealth(W)) :- event(trade(C)), holds(T,wealth(W)).
terminates(T,trade(C),C) :- event(trade(C)), holds(T,C).
terminates(T,transduce(C),C) :- event(transduce(C)), holds(T,C).
%% Initial conditions and time points
holds(0,surface(earth)). % location
holds(0,wealth(1)). % wealth_class
#const t_max=24.
time(0..t_max).
%% Event occurence
{ happens(T,E) } :- time(T), possible(T,E).
:- time(T), not 1 { happens(T,E) } 1.
%% Planning goals
space_cowboy :- happens(T,trade(urnox_hides)).
:- not space_cowboy.
%#hide.
#show happens/2.
#show initiated/2.
#show terminated/2.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment