0

我是 prolog 的新手,我必须编写一个关于水壶的程序。我的问题是关于水壶的初始状态和查询形成。查询将采用以下形式:

?- myPredicate(args), filled(j1,1)

意思是 j1 装满 1 加仑的水。j1 代表其中一个水壶;另一个是j2。最初,我有

filled(j1,0) 
filled(j2,5) 
capacity(j1,2) 
capacity(j2,5) 

如果您向我提供以下信息,我将不胜感激:

问题 A:我必须在我的程序中声明 j1 的初始状态吗?filled(j1,0)

问题 B:我需要让我的程序找到填充(j1,1)的解决方案。为此,我有一些想法,但我不确定的是如何从查询和 myPredicate.

我很困惑,因为我有初始状态filled(j1,0),现在我必须创建一个filled(j1,1)in myPredicate。所以我应该有某种形式的filled(J,Volume)in myPredicate,所以查询返回 true 而不是 false。

如何在filled(J,Voume)内部合并,myPredicate以便在运行上述查询时,我可以显示正确答案?

4

1 回答 1

-2

带有传入参数、初始事实和要执行的迭代任务的示例程序。迭代是通过递归进行的。在每次重新进入之前,与某个参数相关的值可以有效地更新以用于下一次传递。

my_loop(N) :- N > 10.

my_loop(N) :- N =< 10,
    write(N), nl,
    Nextin is N + 1,
    my_loop(Nextin).

:- my_loop(1).

答:
程序需要给定的信息(事实)。它们可以从键盘输入中获得,作为某些谓词的初始参数,或者作为您建议的数据库中的事实。此外,仅建议在特殊情况下,可以将事实硬编码为某些谓词或规则。

下面和上面是将初始信息作为参数传递的示例::- my_predicate(args...).

如果有很多事实,数据库是最好的。每次都需要更改的一些事实最好从键盘获取。否则,它可能无关紧要。

:- my_predicate([fill(j1,0),fill(j2,5)], Answer),
    write(Answer),
    nl.

乙:

请参阅我的_循环示例:

在my_loop中,计数[1..10]的任务是迭代解决的。给定: 1 作为参数传入,主要是因为程序一遍又一遍地做同样的事情:
1. 取一个数字(N);如果太大就退出。否则...
2. 打印它。
3. 计算下一个数 (N+1)
4. 重复

10 是硬编码的。这可能是一个事实:stop_after(10)

现在要操作的数据、my_loop 中的变量N和 myPredicate 中的 { j1,j2 }实际上不需要一遍又一遍地重新分配:参见 my_loop。当需要再次做同样的事情时,只需重新输入计算,但使用不同的参数:

cap(j1,2).
cap(j2,5).

my_predicate(Status, Answer) :-
    got_juice(Status,0),
    Answer=Status.

%%% Instead of changing values, rerun comp. with new values
%%% based on a computation made from the old ones.
my_predicate([filled(j1,J1), filled(j2,J2)], Answer) :-
    Used is J1 + J2,
    got_juice(Used, J), J \= 0,
    cap(j1,C1), cap(C2),
    %% Use cap and filled to add more to filled..
    NextJ1 is J1 + ...,
    NextJ2 is J2 + ...,
    my_predicate(filled(j1,NextJ1), filled(..., Answer).

注意:
上面的谓词只是为了演示 Prolog 中的迭代,使用“myProgaram”的参数。有关实际实现,请参阅 matcheek 评论中建议的程序。

于 2010-12-17T09:53:48.743 回答