% Simulation of Two Balls Bouncing between Two Walls % Procedure to compute the executable situation of length N. proc(executable(N), ?(N = 0) # pi(t, ?(N > 0 & lntp(t)) : pi(a, pi(c, ?(setof(a, natural(a) & poss(a) & time(a,t),c)) : c))) : pi(n, ?(n is N - 1) : executable(n))). % Least-natural-time point. lntp(S,T) :- natural(A), poss(A,S), time(A,T), not (natural(A1), poss(A1,S), time(A1,T1), T1 < T), !. % Action precondition axioms. poss(bounce(B,W,T),S) :- vel(B,V,S), not V = 0, start(S,TS), pos(B,X,S), wallLocation(W,D), T is TS + (D - X)/V, T > TS. poss(collide(B1,B2,T),S) :- vel(B1,V1,S), vel(B2,V2,S), not V1 = V2, start(S,TS), pos(B1,X1,S), pos(B2,X2,S), T is TS - (X1 - X2)/(V1 - V2), T > TS. % Assume no precondition interaction problem; a concurrent action is poss- % ible iff it is coherent, and each of its primitive actions is possible. poss(C,S) :- coherent(C), allPoss(C,S). allPoss([],S). allPoss([A | R],S) :- poss(A,S), allPoss(R,S). % Successor state axioms. pos(B,X,do(C,S)) :- pos(B,X0,S), vel(B,V0,S), start(S,TS), time(C,TC), X is X0 + V0 * (TC - TS). vel(B,V,do(C,S)) :- vel(B,V0,S), ( member(bounce(B,W,T),C), V is -V0 ; (member(collide(B,B1,T),C) ; member(collide(B1,B,T),C)), not member(bounce(B,W,T),C), vel(B1,V1,S), V is V1 ; not member(collide(B,B1,T),C),not member(collide(B1,B,T),C), not member(bounce(B,W,T),C), V is V0 ). % Initial situation. start(s0,0.0). vel(b1,10.0,s0). vel(b2,-5.0,s0). pos(b1,0.0,s0). pos(b2,120.0,s0). wallLocation(w1,0.0). wallLocation(w2,120.0). % Natural action declarations. natural(A) :- A = bounce(B,W,T), ((B = b1 ; B = b2), (W = w1 ; W = w2)) ; A = collide(B1,B2,T), B1 = b1, B2 = b2. % Restore suppressed situation arguments. restoreSitArg(pos(B,X),S,pos(B,X,S)). restoreSitArg(vel(B,V),S,vel(B,V,S)). restoreSitArg(lntp(T),S,lntp(S,T)). restoreSitArg(setof(X,Generator,Set),S,setof(X,holds(Generator,S),Set)). % Action occurrence times. time(bounce(B,W,T),T). time(collide(B1,B2,T),T). % Utilities. prettyPrintSituation(S) :- makeActionList(S,Alist), nl, write(Alist), nl. makeActionList(s0,[]). makeActionList(do(A,S),L) :- makeActionList(S,L1), append(L1,[A],L). simulate(T) :- do(executable(T),s0,S), prettyPrintSituation(S), askForMore. askForMore :- write('More? '), read(n).