如何替换Prolog中的列表?

时间:2017-01-04 16:25:34

标签: prolog

我认为这很容易,但我不知道该怎么做。 我尝试了归档,做一个列表会收到另一个列表但是没有工作。

% H is the head of a coordenate and T the tail
% E is the element that will be placed in the position T
findLine([L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10],H,T,E,NewTray) :-
    H is 1,replace(L1,T,E,N),L1 = N;
    H is 2,replace(L2,T,E,N),L2 = N;
    ...
    H is 10,replace(L10,T,E,N),L10 = N;
    NewTray = [L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10].

我需要L1是本节中的N,我不知道如何创建一个子句来修改find​​Line子句中的L1。我想在create子句中删除所有元素并逐个添加新元素并在属性处调用它:

%L is the list, C a counter and N the new list
 rewrite(L,C,N) :- 
        Q is C,
        removeByIndex(Q,L,R),
        (Q \== 0 ->  rewrite(R,Q-1,N), !.

    removeByIndex(0,[_|T],T):- !.
    removeByIndex(I,[H|T],R):- X is I - 1, removeByIndex(X, T, Y), insert(H, Y, R).

但我继续遇到同样的问题:L1没有被修改:(

想法是修改一条线并替换托盘。

PS:我很抱歉我的英语,但是葡萄牙语论坛中的prolog主题几乎是无效的

1 个答案:

答案 0 :(得分:1)

我真的不确定你在这里想要完成什么,但我可以指出一些让我感到误解的事情。

首先,您将所有变量绑定在顶部,然后您基本上有一个自下而上的其他情况,如下所示:

NewTray = [L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10].

好吧,在任何其他情况下,你永远不会分配给NewTray,所以NewTray大部分时间都没有被实例化。这似乎不太可能是你打算给我的。

其次,您的案例具有以下结构:

H is 1,replace(L1,T,E,N),L1 = N;

这里的第一个错误是H is 1; is/2用于评估算术表达式;这与H = 1之间没有区别,L1N的等价意味着整个谓词可能写成:

findLine([L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10],1,T,E,_) :-
    replace(L1,T,E,L1).
findLine([L0,L1,L2,L3,L4,L5,L6,L7,L8,L9,L10],2,T,E,_) :-
    replace(L2,T,E,L2).
findLine(Line, _, _, Line).

我仍然对你正在尝试做的事感到困惑,看着它。

我怀疑你认为L1在进入关系的路上会有一些价值,并且在使用关系后会突然出现一个新的不同值。这显然是的情况:Prolog中的变量只绑定了一次;您的作业L1 = N或任何不会导致 L1到"收到新值" (因为这样的事情在Prolog中不可能发生);相反,它通知Prolog L1和N应绑定到相同的值。这意味着什么取决于具体情况;例如,如果它们都是基础并且不相等会导致你的谓词失败,但是如果它们中的任何一个是非地面的,它们将接受另一个的值。

我正在看你在这里做了什么,我无能为力,但我认为你实际上是在尝试这样做:

replace([], _, _, []).
replace([H|T], 1, X, [X|T]).
replace([H|T], N, X, [H|Replaced]) :- 
  N > 1, succ(N0, N), replace(T, N0, X, Replaced).

像这样使用:

?- replace([1,2,3,4,5], 3, foo, Result).
Result = [1, 2, foo, 4, 5] 

我不能为我的生活弄清楚你正在尝试做什么,而且我不知道为什么你要打扰绑定列表中的所有变量如果你不是一次性需要它们的话,马上就会出现。

无论如何,我希望这会有所帮助!也许如果你向我们展示更多你正在尝试做的事情,我们将更加清楚如何提供帮助。

修改:在=和统一

上详细说明

让我们与=混在一起,看看会发生什么:

?- X = 3.
X = 3.

可能没什么可惊讶的。

?- 3 = X.
X = 3.

统一与分配不同。如你所见,它不是方向性的。这条线不会用于任何其他语言。

?- X = [1,Y,3].
X = [1, Y, 3].

请注意,Prolog对变量保持空闲没有任何问题。

?- X = [1,Y,3], Y = 2.
X = [1, 2, 3],
Y = 2.

现在,因为Y在两个位置都是相同的,所以当你将Y绑定到2时,X中的中间值也变为2。 Prolog独有的数据结构使用了这个功能(差异列表)。

?- X = [1,Y,3], Q = X, Q = [1,2,3].
X = Q, Q = [1, 2, 3],
Y = 2.

现在让我感兴趣的是我们没有明确告诉Prolog Y是2. Prolog通过统一来推断这一点。你可以在这里看到更多的例子:

?- X = [H|T], H = 3, T = [4,5].
X = [3, 4, 5],
H = 3,
T = [4, 5].

所以我们在这里说,X由H和T组成,然后告诉它H和T是什么。但Prolog的统一并不关心你做事的顺序:

?- X = [H|T], X = [1,2,3].
X = [1, 2, 3],
H = 1,
T = [2, 3].

统一是传递性的。

那么当Prolog无法统一时会发生什么?

?- X = [1,Y,3], Q = X, Q = [1,2,3], Y = 4.
false.

第一步Y必须为2,但最后一步必须为4。一旦变量被绑定,就不会改变它。这只是一种更复杂的说法:

?- X = 2, X = 4.
false.

Prolog没有" assignables",只是变量。