Created
July 4, 2018 08:48
-
-
Save dariusf/e73292df675a9f63117d058c9b356b9b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% 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