Files
mercury/tests/dppd/imperative_solve_impl.m
Zoltan Somogyi 9cacd33f47 Remove "is" as a synonym for "=", step 1.
This first step deals with the consequences of such removal.
The removal itself will happen in stage 2. That step will
add "is" to the prolog module in the library.

compiler/add_pred.m:
    Prepare for "is" being in the prolog module.

compiler/options.m:
    Add a way to test whether the change to add_pred.m is in the
    installed compiler.

tests/accumulator/base.m:
tests/accumulator/call_in_base.m:
tests/accumulator/chain.m:
tests/accumulator/commutative.m:
tests/accumulator/construct_test.m:
tests/accumulator/dcg.m:
tests/accumulator/deconstruct_test.m:
tests/accumulator/disj.m:
tests/accumulator/func.m:
tests/accumulator/heuristic.m:
tests/accumulator/highorder.m:
tests/accumulator/identity.m:
tests/accumulator/inter.m:
tests/accumulator/nonrec.m:
tests/accumulator/out_to_in.m:
tests/accumulator/qsort.m:
tests/accumulator/simple.m:
tests/accumulator/split.m:
tests/accumulator/swap.m:
tests/benchmarks/cqueens.m:
tests/benchmarks/crypt.m:
tests/benchmarks/deriv.m:
tests/benchmarks/deriv2.m:
tests/benchmarks/nrev.m:
tests/benchmarks/poly.m:
tests/benchmarks/primes.m:
tests/benchmarks/qsort.m:
tests/benchmarks/query.m:
tests/benchmarks/tak.m:
tests/debugger/interactive.m:
tests/declarative_debugger/Mercury.options:
tests/declarative_debugger/io_read_bug.m:
tests/declarative_debugger/queens.exp:
tests/declarative_debugger/queens.m:
tests/dppd/imperative_solve_impl.m:
tests/dppd/map_impl.m:
tests/dppd/max_length_impl.m:
tests/dppd/sum.m:
tests/dppd/upto_sum_impl.m:
tests/par_conj/dep_par_21.m:
tests/tabling/seq.m:
tests/term/dds3_14.m:
tests/term/mmatrix.m:
tests/term/money.m:
tests/term/occur.m:
tests/term/pl4_5_2.m:
tests/term/queens.m:
tests/typeclasses/inference_test.m:
tests/typeclasses/inference_test_2.m:
tests/valid/lazy_list.m:
tests/warnings/duplicate_const.m:
    Replace calls to "is" with unifications. In many places,
    bring programming style up to date.
2020-08-21 10:42:37 +10:00

161 lines
4.5 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ts=4 sw=4 et ft=mercury
%---------------------------------------------------------------------------%
:- module imperative_solve_impl.
:- interface.
:- import_module assoc_list.
:- type var == string.
:- type env == assoc_list(var, int).
:- pred power_2_5(env::in, env::out) is semidet.
:- implementation.
:- import_module bool.
:- import_module int.
:- import_module list.
:- import_module pair.
power_2_5(!Env) :-
power(2, 5, !Env).
:- pred store(env::in, var::in, int::in, env::out) is det.
store([], Key, Value, [Key - Value]).
store([Key0 - Value0 | T0], Key1, Value1, [Key - Value | T]) :-
( if Key0 = Key1 then
Key = Key0,
Value = Value1,
T = T0
else
Key = Key0,
Value = Value0,
store(T0, Key1, Value1, T)
).
:- pred lookup(var::in, env::in, int::out) is semidet.
lookup(Key1, [Key2 - Value0 | T], Value) :-
( if Key1 = Key2 then
Value = Value0
else
lookup(Key1, T, Value)
).
:- pred power(int::in, int::in, env::in, env::out) is semidet.
power(Base, Power, E1, EOut) :-
execute_statement(let("base", int(Base)), E1, E2),
execute_statement(let("power", int(Power)), E2, E3),
execute_statement(seq(seq(let("x", int(1)), let("result", var("base"))),
while_do('<'(var("x"), var("power")),
seq(let("x", '+'(var("x"), int(1))),
let("result", '*'(var("result"), var("base")))))),
E3, EOut).
:- type stmt
---> null
; let(var, expr)
; if(test, stmt, stmt)
; repeat_until(stmt, test)
; while_do(test, stmt)
; seq(stmt, stmt).
:- pred execute_statement(stmt::in, env::in, env::out) is semidet.
execute_statement(null, Env, Env).
execute_statement(let(V, Expr), Env, NEnv) :-
eval_expression(Expr, Env, Val),
store(Env, V, Val, NEnv).
execute_statement(if(Tst, Thn, Els), Env, NEnv) :-
eval_test(Tst, Env, Bool),
execute_cond_continuation(Bool, Thn, Els, Env, NEnv).
execute_statement(repeat_until(Loop, Tst), Env, NEnv) :-
execute_statement(Loop, Env, IntEnv),
eval_test(Tst, IntEnv, Bool),
execute_cond_continuation(Bool, null,
repeat_until(Loop, Tst), IntEnv, NEnv).
execute_statement(while_do(Tst, Loop), Env, NEnv) :-
eval_test(Tst, Env, Bool),
execute_cond_continuation(Bool, seq(Loop, while_do(Tst, Loop)),
null, Env, NEnv).
execute_statement(seq(St1, St2), Env, NEnv) :-
execute_statement(St1, Env, IntEnv),
execute_statement(St2, IntEnv, NEnv).
:- pred execute_cond_continuation(bool::in, stmt::in, stmt::in,
env::in, env::out) is semidet.
execute_cond_continuation(yes, Thn, _Els, Env, NEnv) :-
execute_statement(Thn, Env, NEnv).
execute_cond_continuation(no, _Thn, Els, Env, NEnv) :-
execute_statement(Els, Env, NEnv).
:- type test
---> '<'(expr, expr)
; '=<'(expr, expr)
; '>'(expr, expr)
; '>='(expr, expr).
:- pred eval_test(test::in, env::in, bool::out) is semidet.
eval_test('<'(X, Y), Env, Bool) :-
eval_expression(X, Env, VX),
eval_expression(Y, Env, VY),
get_bool(VX < VY, Bool).
eval_test('=<'(X, Y), Env, Bool) :-
eval_expression(X, Env, VX),
eval_expression(Y, Env, VY),
get_bool(VX =< VY, Bool).
eval_test('>'(X, Y), Env, Bool) :-
eval_expression(X, Env, VX),
eval_expression(Y, Env, VY),
get_bool(VX > VY, Bool).
eval_test('>='(X, Y), Env, Bool) :-
eval_expression(X, Env, VX),
eval_expression(Y, Env, VY),
get_bool(VX >= VY, Bool).
:- pred get_bool((pred)::in((pred) is semidet), bool::out) is det.
get_bool(Tst, Res) :-
( if call(Tst) then
Res = yes
else
Res = no
).
:- type expr
---> int(int)
; var(string)
; '+'(expr, expr)
; '-'(expr, expr)
; '*'(expr, expr)
; '/'(expr, expr).
:- pred eval_expression(expr::in, env::in, int::out) is semidet.
eval_expression(int(X), _Env, X).
eval_expression(var(V), Env, Val) :-
lookup(V, Env, Val).
eval_expression('+'(X, Y), Env, Val) :-
eval_expression(X, Env, VX),
eval_expression(Y, Env, VY),
Val = VX + VY.
eval_expression('-'(X, Y), Env, Val) :-
eval_expression(X, Env, VX),
eval_expression(Y, Env, VY),
Val = VX - VY.
eval_expression('*'(X, Y), Env, Val) :-
eval_expression(X, Env, VX),
eval_expression(Y, Env, VY),
Val = VX * VY.
eval_expression('/'(X, Y), Env, Val) :-
eval_expression(X, Env, VX),
eval_expression(Y, Env, VY),
Val = VX // VY.