summaryrefslogtreecommitdiff
path: root/prolog/problems/algol/algol_if_3
diff options
context:
space:
mode:
authorTimotej Lazar <timotej.lazar@fri.uni-lj.si>2016-05-29 16:33:27 +0200
committerTimotej Lazar <timotej.lazar@fri.uni-lj.si>2016-05-29 16:33:27 +0200
commit8204263c09d77c2b4a8648aa9cad1bba97a9a5f5 (patch)
treed79aff84311a7bf8cd52838ca22ab5c504cd912e /prolog/problems/algol/algol_if_3
parent6a5096c18de91c7b4f438b7698e24c15146fdb77 (diff)
Prolog: add initial programs for algol problems
Diffstat (limited to 'prolog/problems/algol/algol_if_3')
-rw-r--r--prolog/problems/algol/algol_if_3/common.py91
1 files changed, 90 insertions, 1 deletions
diff --git a/prolog/problems/algol/algol_if_3/common.py b/prolog/problems/algol/algol_if_3/common.py
index 26bea96..9198831 100644
--- a/prolog/problems/algol/algol_if_3/common.py
+++ b/prolog/problems/algol/algol_if_3/common.py
@@ -56,7 +56,7 @@ apply177(In, Out, fun(In, Out, Goals)) :-
loop177( State0, Mcond, _, State0) :-
apply177( State0, false, Mcond), !.
-loop177( S0, Mcond, MBody, S) :-
+loop177( S0, Mcond, MBody, S) :-
copy_term( MBody, MBodyCopy),
apply177( S0, S1, MBody),
loop177( S1, Mcond, MBodyCopy, S).
@@ -83,3 +83,92 @@ eval177( E1 / E2, State, Val) :- !,
eval177( E2, State, V2),
Val is V1 / V2.
'''
+
+initial = '''\
+% program
+algol_if(fun(S0, S, apply([printout=[]|S0], S, Minstructs))) -->
+ [begin], instructs(Minstructs), [end].
+
+% sequence of instructions
+instructs(Minstr) --> instr(Minstr).
+instructs(fun(S0,S,
+ (apply(S0,S1,Minstr),
+ apply(S1,S,Minstructs))))
+ -->
+ instr(Minstr), instructs(Minstructs).
+
+% statement (instruction)
+instr(Massign) --> assign(Massign).
+
+% put the current value of a variable into the output list
+instr(fun(S0, [printout = L1|S1],
+ (memb(X = V,S0),
+ del(printout = L0, S0, S1),
+ conc(L0, [V], L1))))
+ -->
+ [print(X)].
+
+% while-loop
+instr(fun(S0, S,
+ loop(S0, Mcond, Minstructs, S)))
+ -->
+ [while], cond(Mcond), [do, begin], instructs(Minstructs), [end].
+
+% assignment statement
+assign(fun(S0, [X = Value|S1],
+ (apply(S0, Value, Mexpr),
+ del(X = _, S0, S1))))
+ -->
+ var(X), [':='], expr(Mexpr).
+
+% conditional expression
+cond(fun(S, TruthVal,
+ (apply(S, Val1, ME1),
+ apply(S, Val2, ME2),
+ (Val1 < Val2, !, TruthVal = true ; TruthVal = false))))
+ -->
+ expr(ME1), ['<'], expr(ME2).
+
+% variable
+var(X) --> [X], { atom(X) }.
+
+% expression
+expr(fun(S, Value, eval(Expr, S, Value))) -->
+ [Expr]. % Expr is a Prolog arithmetic expression, e.g. x + 2*y + 3
+
+% helper predicates
+% function call
+apply(In, Out, fun(In, Out, Goals)):-
+ call(Goals).
+
+% loop
+loop(State0, Mcond, _, State0) :-
+ apply(State0, false, Mcond), !. % condition is false
+loop(S0, Mcond, MBody, S) :-
+ copy_term(MBody, MBodyCopy), % copy goals
+ apply(S0, S1, MBody), % run loop body
+ loop(S1, Mcond, MBodyCopy, S). % next iteration
+
+% expression evaluation
+eval(N, _, N) :-
+ number(N), !.
+eval(X, State, Val) :- % a program variable
+ atom(X), !,
+ memb(X = Val, State).
+eval(E1 + E2, State, Val) :- !,
+ eval(E1, State, V1),
+ eval(E2, State, V2),
+ Val is V1 + V2.
+eval(E1 - E2, State, Val) :- !,
+ eval(E1, State, V1),
+ eval(E2, State, V2),
+ Val is V1 - V2.
+eval(E1 * E2, State, Val) :- !,
+ eval(E1, State, V1),
+ eval(E2, State, V2),
+ Val is V1 * V2.
+eval(E1 / E2, State, Val) :- !,
+ eval(E1, State, V1),
+ eval(E2, State, V2),
+ Val is V1 / V2.
+'''