使用prolog程序创建新变量

时间:2016-09-28 14:19:14

标签: prolog clpfd

我对程序内部的变量创建有疑问。 假设我有一个函数(? - 不确定这里的措辞),这是/ 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]

但现在没有运气。

程序就是这样的: - &gt;

 ?- 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.

2 个答案:

答案 0 :(得分:2)

您可以尝试“隐藏”输出变量,并自己编写,就像您已经在做的那样:只需从谓词定义的头部删除第二个参数:

solve(N) :-
    % rest unchanged

然后:

?- solve(30).

1+2+3+5=11
true.

但这确实适得其反。 “Prolog”方式只是使用顶层进行打印。例如,我会从您的定义中完全删除手册:

:- 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).

答案 1 :(得分: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]无效,因为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.