/* * RAM simulator in HyperLMNtal(hyperlmn) * 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($l,LN, add($b),$a), mem($b,Y) \ mem($a,X), prog_counter($l) :- Z = X + Y, hlink(LN) | mem($a,Z), prog_counter(LN). % subtract value of register B from register A sub@@ prog($l,LN, sub($b),$a), mem($b,Y) \ mem($a,X), prog_counter($l) :- Z = X - Y, hlink(LN) | mem($a,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($l,LN,cjump($r),A), mem($r,0) \ prog_counter($l) :- hlink(A) | prog_counter(A). cjumpN@@ prog($l,LN,cjump($r),A), mem($r,X) \ prog_counter($l) :- X =\= 0, hlink(LN) | prog_counter(LN). % halt halt@@ prog($l,LN,halt,_) \ prog_counter($l) :- . % invalid instruction % prog_counter(L) :- int(L) | true. init(N) :- new($x), new($y), new($z), new($a) | prog_counter($x), mem($x,1), mem($y,N), mem($z,0), prog($x,$y, add($x), $z), prog($y,$z, sub($x), $y), prog($z,$x, cjump($y), $a). make_mem(M) :- M > 3, M1 = M-1, new($x) | make_mem(M1), mem($x,0), prog($x, $x, halt, $x). }. 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).