如何替换 Prolog 中的列表? [英] How can I replace a list in Prolog?

查看:38
本文介绍了如何替换 Prolog 中的列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为这很容易,但我不知道该怎么做.我尝试通过归因,做一个列表接收另一个列表但不起作用.

I think it's very easy but I have no idea how to do that. I tried by attribuition, doing a list receive another list but don't work.

% 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,我不知道如何创建一个子句来修改子句 findLine 中的 L1.我想在 create 子句中删除所有元素并一个一个添加新元素并在属性位置调用它:

I need that L1 be the N in this clause, I don't know how I can create a clause to modify the L1 inside the clause findLine. I thought in create clause to remove all elements and add the new ones one by one and call this at the attribuition place:

%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 没有被修改:(

But I continous with the same problem: the L1 are not modified :(

这个想法是修改一行并在托盘上替换.

The idea is modify a line and replace on the tray.

PS:对不起我的英语,但葡萄牙语论坛的序言主题几乎是非原生的

PS: I'm sorry for my english, but the prolog topics are almost inative in the portuguese forum

推荐答案

我真的不确定你想在这里完成什么,但我可以指出一些让我印象深刻的事情,因为这是误解的征兆.

I'm really unsure what you're trying to accomplish here, but I can point to a few things that strike me as symptoms of a misunderstanding.

>

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

First of all, you bind all the variables at the top and then you have essentially a bottom-out else case that looks like this:

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

好吧,在任何其他情况下,您都不会分配给 NewTray,因此 NewTray 在大多数情况下都不会被实例化.这似乎不是你对我的意图.

Well, you never assign to NewTray in any of your other cases, so NewTray is going to be uninstantiated most of the time. That does not seem likely to be what you intend to me.

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

Second, your cases have this structure:

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

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

First mistake here is that H is 1; is/2 is for evaluating arithmetic expressions; there's no difference between this and H = 1, and the equivalence of L1 and N means that this whole predicate could probably be written as:

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

我仍然对你想要做什么感到困惑,看着那个.

I'm still confused by what you're trying to do, looking at that.

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

I suspect that you think L1 will have some value on the way into the relation and suddenly have a new, different value after the relation is used. That is emphatically not the case: variables in Prolog are bound exactly once; your assignment L1 = N or whatever is not going to cause L1 to "receive a new value" (because such a thing cannot happen in Prolog); instead it informs Prolog that L1 and N should be bound to the same value. What this means depends on circumstances; if they are both ground and not equal it will cause your predicate to fail, for instance, but if either of them is non-ground they will accept the value of the other.

我正在查看您在这里做什么,我不禁认为您实际上是在尝试这样做:

I'm looking at what you're doing here and I can't help but think that you're essentially trying to do this:

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] 

我终其一生都无法弄清楚您要做什么,而且我不知道如果您不需要,您为什么要一次性绑定列表中的所有变量一次全部完成.

I just can't for the life of me figure out what you're trying to do, and I don't know why you're bothering to bind all the variables in your list at once if you don't need them all at once.

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

Anyway, I hope this helps! Maybe if you show us more of what you're trying to do it will be more clear how we can help.

编辑:详细说明= 和统一

让我们使用 = 看看会发生什么:

Let's mess around with = and see what happens:

?- X = 3.
X = 3.

这可能没什么好奇怪的.

Probably nothing surprising about this.

?- 3 = X.
X = 3.

统一与分配不同.如您所见,它没有方向性.这条线在任何其他语言中都行不通.

Unification is different from assignment. As you can see, it is not directional. This line would not have worked in any other language.

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

请注意,Prolog 在变量保持空闲方面没有问题.

Notice that Prolog has no issues with having variables remain free.

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

现在,由于 Y 在两个位置上相同,当您将 Y 绑定到 2 时,X 中的中间值也变为 2.Prolog 有一些独特的数据结构利用了这个特性(差异列表).

Now, because Y is the same in both positions, when you bound Y to 2, the middle value in X became 2 as well. There are data structures unique to Prolog that make use of this feature (difference lists).

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

现在有趣的是,我们没有明确告诉 Prolog Y 是 2.Prolog 通过统一推断出这一点.您可以在此处查看更多示例:

Now what makes this interesting is that we did not explicitly tell Prolog that Y is 2. Prolog inferred this by unification. You can see some more examples of that here:

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

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

So here we said, X is composed of H and T and then told it what H and T are. But Prolog's unification doesn't care much about the order you do things:

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

统一是可传递的.

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

So what happens when Prolog cannot unify?

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

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

Y has to be 2 for the first step, but it has to be 4 for the last step. Once a variable is bound, there's no changing it. This is just a more complex way of saying:

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

Prolog 没有可赋值",只有变量.

Prolog does not have "assignables", just variables.

这篇关于如何替换 Prolog 中的列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆