/* * RAM simulator in LMNtal(lmn-int) * Author: Seiji OGAWA, 2011-03-31 * * Examples are taken from: * http://dtai.cs.kuleuven.be/CHR/examples.shtml * * If you'd like to change parameter N, * please change the 1st argument of start("N"). * */ { % add value of register B to register A add@@ prog(L1,LN, add(B1),A1), mem(B2,Y) \ mem(A2,X), prog_counter(L2) :- A1 =:= A2, B1 =:= B2, L1 =:= L2, Z = X + Y, int(LN) | mem(A1,Z), prog_counter(LN). % subtract value of register B from register A sub@@ prog(L1,LN, sub(B1),A1), mem(B2,Y) \ mem(A2,X), prog_counter(L2) :- A1 =:= A2, B1 =:= B2, L1 =:= L2, Z = X - Y, int(LN) | mem(A1,Z), prog_counter(LN). /* % multiply register A with value of register B mul@@ prog(L1,LN,mult(B1),A1), mem(B2,Y) \ mem(A2,X), prog_counter(L2) :- A1 =:= A2, B1 =:= B2, L1 =:= L2, Z = X * Y, int(LN) | mem(A1,Z), prog_counter(LN). % divide register A by value of register B div@@ prog(L1,LN, div(B1),A1), mem(B2,Y) \ mem(A2,X), prog_counter(L2) :- A1 =:= A2, B1 =:= B2, L1 =:= L2, Z = X / Y, int(LN) | mem(A1,Z), prog_counter(LN). % put the value in register B in register A move@@ prog(L1,LN,move(B1),A1), mem(B2,X) \ mem(A2,Y), prog_counter(L2) :- A1 =:= A2, B1 =:= B2, L1 =:= L2, int(X), int(Y), int(LN) | mem(A1,X), prog_counter(LN). % put the value in register in register A i_move@@ prog(L1,LN,i_move(B1),A1), mem(B2,C1), mem(C2,X) \ mem(A2,Y), prog_counter(L2) :- A1 =:= A2, B1 =:= B2, C1 =:= C2, L1 =:= L2, int(X), int(Y), int(LN) | mem(A1,X), prog_counter(LN). % put the value in register B in register move_i@@ prog(L1,LN,move_i(B1),A1), mem(B2,X), mem(A2,C1) \ mem(C2,Y), prog_counter(L2) :- A1 =:= A2, B1 =:= B2, C1 =:= C2, L1 =:= L2, int(X), int(Y), int(LN) | mem(C1,X), prog_counter(LN). % put the value B in register A -> redundant if consts are in init mem const@@ prog(L1,LN,const(B),A1) \ mem(A2,X), prog_counter(L2) :- A1 =:= A2, L1 =:= L2, int(B), int(X), int(LN) | mem(A1,B), prog_counter(LN). %zero@@ %prog(L1,LN,clr,A1) \ mem(A2,X), prog_counter(L2) :- % same as const(0) % A1 =:= A2, L1 =:= L2, int(X), int(LN) | % mem(A1,0), prog_counter(LN). % unconditional jump to label A jump@@ prog(L1,LN,jump,A) \ prog_counter(L2) :- L1 =:= L2, int(A) | prog_counter(A). */ % jump to label A if register R is zero, otherwise continue cjump0@@ prog(L1,LN,cjump(R1),A), mem(R2,0) \ prog_counter(L2) :- L1 =:= L2, R1 =:= R2, int(A) | prog_counter(A). cjumpN@@ prog(L1,LN,cjump(R1),A), mem(R2,X) \ prog_counter(L2) :- X =\= 0, L1 =:= L2, R1 =:= R2, int(LN) | prog_counter(LN). % halt //halt@@ //prog(L1,LN,halt,_) \ prog_counter(L2) :- L1 =:= L2 | . % invalid instruction % prog_counter(L) :- int(L) | true. make_mem(M) :- M > 3, M1 = M-1 | make_mem(M1), mem(M,0), prog(M, M1, halt, 0). init(N) :- prog_counter(1), mem(1,1), mem(2,N), mem(3,0), prog(1,2, add(1), 3), prog(2,3, sub(1), 2), prog(3,1, cjump(2), 4). }. start(1250). start(S), {$p, @p}/ :- int(S) | {make_mem(30), init(S), $p, @p}, '$callback'(gettime, start). %init(S), const(C), {prog_counter(P), mem(1,X), mem(2,Y), mem(3,Z), $p, @p}/ :- % int(C), int(P), int(X), int(Y), int(Z), S > 0, S1 = S-1 | init(S1), const(C), {init(C), $p, @p}. start(S), {$p[], @p}/ :- float(S) | start(S), '$callback'(gettime, end). end(E), start(S) :- T = E-.S | time(T).