from operator import itemgetter import socket import prolog.engine import prolog.util from server.hints import Hint, HintPopup id = 177 number = 20 visible = True facts = None solution = '''\ algol_if(fun(S0,S,apply177([printout=[]|S0],S,Minstructs))) --> [begin], instructs177(Minstructs), [end]. instructs177(Minstr) --> instr177(Minstr). instructs177(fun(S0,S, (apply177(S0,S1,Minstr), apply177(S1,S,Minstructs)))) --> instr177(Minstr), instructs177(Minstructs). instr177(Massign) --> assign177(Massign). instr177(fun(S0,[printout = L1|S1], (memb(X = V,S0), del(printout = L0,S0,S1), conc(L0,[V],L1)))) --> [print(X)]. instr177(fun(S0,S, loop177(S0,Mcond,Minstructs,S))) --> [while], cond177(Mcond), [do,begin], instructs177(Minstructs), [end]. instr177(fun(S0, S, (apply177(S0, true, Mcond), !, apply177(S0, S, MinstructsA) ; apply177(S0, S, MinstructsB)))) --> [if], cond177(Mcond), [then], instructs177(MinstructsA), [else], instructs177(MinstructsB), [end]. assign177(fun(S0,[X = Value|S1], (apply177(S0,Value,Mexpr), del(X = _,S0,S1)))) --> var177(X), [:=], expr177(Mexpr). cond177( fun( S, TruthVal, (apply177(S,Val1,ME1), apply177(S,Val2,ME2), (Val1 < Val2,!,TruthVal = true ; TruthVal = false)))) --> expr177(ME1), [<], expr177(ME2). var177(X) --> [X], {atom(X)}. expr177(fun(S,Value,eval(Expr,S,Value))) --> [Expr]. apply177(In, Out, fun(In, Out, Goals)) :- call(Goals). loop177( State0, Mcond, _, State0) :- apply177( State0, false, Mcond), !. loop177( S0, Mcond, MBody, S) :- copy_term( MBody, MBodyCopy), apply177( S0, S1, MBody), loop177( S1, Mcond, MBodyCopy, S). eval177( N, _, N) :- number177( N), !. eval177( X, State, Val) :- % A program variable atom( X), !, memb( X = Val, State). eval177( E1 + E2, State, Val) :- !, eval177( E1, State, V1), eval177( E2, State, V2), Val is V1 + V2. eval177( E1 - E2, State, Val) :- !, eval177( E1, State, V1), eval177( E2, State, V2), Val is V1 - V2. eval177( E1 * E2, State, Val) :- !, eval177( E1, State, V1), eval177( E2, State, V2), Val is V1 * V2. eval177( E1 / E2, State, Val) :- !, eval177( E1, State, V1), 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. ''' test_cases = [ ('findall(W, (W = [_], algol_if(_, W, [])), Words), Words == []', [{}]), ('algol_if(F, [begin,if,a,<,0,then,a,:=,0-a,else,a,:=,a,end,end], []), \ apply([a= -2], Out, F), msort(Out, OutSorted), \ OutSorted == [a=2,printout=[]]', [{}]), ('algol_if(F, [begin,if,0,<,a,then,print(a),else,b,:=,a+5,print(b),end,end], []), \ apply([a= -2,b=0], Out, F), msort(Out, OutSorted), \ OutSorted == [a= -2,b=3,printout=[3]]', [{}]), ] def test(code, aux_code): n_correct = 0 engine_id = None try: engine_id, output = prolog.engine.create(code=code+aux_code, timeout=1.0) if engine_id is not None and 'error' not in map(itemgetter(0), output): # Engine successfully created, and no syntax error in program. for query, answers in test_cases: if prolog.engine.check_answers(engine_id, query=query, answers=answers, timeout=1.0): n_correct += 1 except socket.timeout: pass finally: if engine_id: prolog.engine.destroy(engine_id) hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_cases)}}] return n_correct, len(test_cases), hints