2016-09-28 3 views
2

У меня вопрос относительно переменной, создаваемой внутри программы. Допустим, у меня есть функция (? - не уверен в формулировке здесь), которая есть/2, есть способ изменить ее на/1?Создание новой переменной с пролог-программой

:- use_module(library(clpfd)). 
solve(N, L):- 
     L = [A,B,C,D], 
     L ins 1..sup, 
     N #= A * B * C * D, 
     all_distinct(L), 
     A #< B, B #< C, C#< D, 
     labeling([],L),nl, 
     Z #= A+B+C+D, 
     write(A+B+C+D=Z). 

Есть ли возможность фактически решить проблему (N), где L создается на ходу. Пробовал с помощью обоих,

L is [A,B,C,D], 

или

L = [], 
L is [A,B,C,D] 

но не повезло прямо сейчас.

Программа работает так: ->

?- solve(30,Elements). 

1+2+3+5=11 
Elements = [1, 2, 3, 5]. 

?-  solve(60, Elements). 

1+2+3+10=16 
Elements = [1, 2, 3, 10] ; 

1+2+5+6=14 
Elements = [1, 2, 5, 6] ; 

1+3+4+5=13 
Elements = [1, 3, 4, 5] ; 
false. 

ответ

1

Да, но тогда вы получите, например:

?- solve(30). 

1+2+3+5=11 
true. 

?- solve(60). 

1+2+3+10=16 
true ; 

1+2+5+6=14 
true ; 

1+3+4+5=13 
true ; 
false. 

Если это то, что вы ищете просто написать solve(N) вместо solve(N, L):

:- use_module(library(clpfd)). 
solve(N):- 
     L = [A,B,C,D], 
     L ins 1..sup, 
     N #= A * B * C * D, 
     all_distinct(L), 
     A #< B, B #< C, C#< D, 
     labeling([],L),nl, 
     Z #= A+B+C+D, 
     write(A+B+C+D=Z). 

Имейте в виду, что L is [A,B,C,D] не является вали d, потому что is/1 используется для арифметических выражений, а не для унификации. Вы должны использовать =/2, который объединяет L с четырьмя списками элементов.

Если вы хотите, чтобы напечатать список можно было бы написать:

:- use_module(library(clpfd)). 
solve(N):- 
     L = [A,B,C,D], 
     L ins 1..sup, 
     N #= A * B * C * D, 
     all_distinct(L), 
     A #< B, B #< C, C#< D, 
     labeling([],L),nl, 
     Z #= A+B+C+D, 

     writeln(A+B+C+D=Z), 
     write("Elements="), 
     write(L). 

Пример:

?- solve(30). 

1+2+3+5=11 
Elements=[1,2,3,5] 
true. 
+0

Есть ли способ сделать это с помощью решения (N), но по-прежнему показывать элементы в списке? –

+0

Только если вы распечатываете список (используя запись - для печати каждого элемента L). – coder

+0

Обновлен ответ, чтобы распечатать список – coder

2

Вы можете попробовать «шкурой» выходной переменной, и написать его самостоятельно, как и вы уже выполните: просто удалите второй аргумент из заголовка определения вашего предиката:

solve(N) :- 
    % rest unchanged 

Тогда:

?- solve(30). 

1+2+3+5=11 
true. 

Но это действительно контрпродуктивно. «Пролог» - это просто использовать верхний уровень для печати. Например, я бы полностью удалить вручную письма из вашего определения:

:- use_module(library(clpfd)). 
solve(N, Z-L):- 
     L = [A,B,C,D], 
     L ins 1..sup, 
     N #= A * B * C * D, 
     all_distinct(L), 
     A #< B, B #< C, C#< D, 
     Z #= A+B+C+D, 
     labeling([],L). 

Тогда:

?- solve(30, Solution). 
Solution = 11-[1, 2, 3, 5]. 

Однако даже это не является оптимальным. Лучше оставить мечение за пределами предиката, который создает ограничения:

solve(N, Z-L):- 
     L = [A,B,C,D], 
     L ins 1..sup, 
     N #= A * B * C * D, 
     all_distinct(L), 
     A #< B, B #< C, C#< D, 
     Z #= A+B+C+D. 

Если нет остаточных ограничений, вы все равно получите решение сразу:

?- solve(30, Solution). 
Solution = 11-[1, 2, 3, 5]. 

(Мы не называем labeling/2 на всех больше!)

Если вы особенно любите формат решения A + B + ... = Sum, вы можете допустить, чтобы верхний уровень выполнял печать для вас. Просто измените голова вашего предиката:

solve(N, A+B+C+D=Z) :- 
    % rest as in the last example 

Тогда:

?- solve(30, Solution). 
Solution = (1+2+3+5=11). 
Смежные вопросы