beroal (beroal) wrote in ru_declarative,
beroal
beroal
ru_declarative

Пролог, порядок целей в зависимости от данных

Есть ли вариант Пролога, который выбирает порядок целей в зависимости от данных? Пример.
code_rem(zero) --> [false].
code_rem(succ(zero)) --> [true].
code_n(zero) --> [false].
code_n(succ(N)) --> [true], {div_mod(N, succ(succ(zero)), Q, R)}, code_rem(R), code_n(Q).

code_n работает только как print. Если поменять порядок атомов:
code_n(succ(N)) --> [true], code_rem(R), code_n(Q), {div_mod(N, succ(succ(zero)), Q, R)}.

работает только как parse.

[Update 2015-08-03. Сделал с помощью when. Правда, пришлось подправить и арифметику. Теперь приходится обходиться без DCG. Зато теперь порядок целей в программе не важен.
add(X, Y0, Y1) :- when((nonvar(Y0); nonvar(Y1)), add1(X, Y0, Y1)).
add1(X, zero, X).
add1(X, succ(Y0), succ(Y1)) :- add(X, Y0, Y1).
le(X, Y) :- add(_, X, Y).
lt(X, Y) :- le(succ(X), Y).

mult_add(R, Y, Q, X) :- when((nonvar(Q); nonvar(X)), mult_add1(R, Y, Q, X)).
mult_add1(R, _, zero, R).
mult_add1(R, Y, succ(Q), X) :- mult_add(R, Y, Q, X1), add(X1, Y, X).
mult(Y, Q, X) :- mult_add(zero, Y, Q, X).
div_mod(X, Y, Q, R) :- mult_add(R, Y, Q, X), lt(R, Y).

code_rem(N, S0, S) :- when((nonvar(N); nonvar(S0)), code_rem1(N, S0, S)).
code_rem1(zero, [false|S], S).
code_rem1(succ(zero), [true|S], S).
code_n(N, S0, S) :- when((nonvar(N); nonvar(S0)), code_n1(N, S0, S)).
code_n1(zero, [false|S], S).
code_n1(succ(N), [true|S0], S)
	:- div_mod(N, succ(succ(zero)), Q, R)
	, code_rem(R, S0, S1)
	, code_n(Q, S1, S)
	.

]
Tags: parse, prolog, termination
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 6 comments