0

首先让我声明这是作为家庭作业提供的课堂练习的一部分。但是,整个作业比这个问题的主题要复杂得多。所以..

我正在搜索给定谓词的两个列表。我的目标是比较此列表中的相应元素并确定第一个是否更大。如果是,那么我最终需要返回所有这些术语的总和。这是我到目前为止所拥有的:

isumrow([], [], Iresult) :- 
    Iresult is 0.
isumrow([Hi1row | Ti1row], [Hi2row | Ti2row], Iresult) :-   
    if((Hi1row - Hi2row), IsumDiff, Hi1row),
    NewIresult is IsumDiff + Iresult,
    isumrow(Ti1row, Ti2row, NewIresult),
    Iresult is NewIresult.

if(Diff, Iresult, Entry) :-
    Diff > 0,                       

    Iresult is Entry.

if(_, Iresult, _) :-
    Iresult is 0.

出于某种原因,我在作业的某个地方搞砸了,我不确定在哪里。任何提示将不胜感激。同样,这是我正在工作的更大任务的一部分,但我无法得到这个。谢谢

4

2 回答 2

1
isumrow([], [], Iresult) :-
    Iresult is 0.

isumrow([Hi1row | Ti1row], [Hi2row | Ti2row], Iresult) :-
    if((Hi1row - Hi2row), IsumDiff, Hi1row),              
    NewIresult is IsumDiff + Iresult, 
    isumrow(Ti1row, Ti2row, NewIresult), 
    Iresult is NewIresult. 

if(Diff, Iresult, Entry) :- 
    Diff > 0,                                            
    Iresult is Entry. 

if(_, Iresult, _) :- 
    Iresult is 0. 
于 2009-12-28T08:03:28.027 回答
0

我将尝试对您的代码进行尽可能少的更改。

绝对错误的一件事是您尝试计算差异的位置。Prolog 仅在使用is运算符时进行算术计算。你的代码:

if((Hi1row - Hi2row), IsumDiff, Hi1row),

只是将 (XY) 形式的表达式传递给if谓词,而不是计算它。稍后在内部if,您不计算差异,而是尝试将表达式与零进行比较……但失败了,因为您只能将数字与数字进行比较,而不能与表达式进行比较——并且Diff被分配给一个表达式。

如果你重写 if 的第一个子句,它会起作用(即使你也应该is在这里去掉它):

if((X-Y), Iresult, Entry) :-
    X > Y,
    Iresult is Entry.

这样,您的if谓词将从表达式中获取 X 和 Y 以便能够比较它们。

此外,您需要避免使用if谓词来产生两个可能的答案。if即使 X>Y: 在回溯过程中,您的第二个子句也会被调用。最简单的方法是放在!第一个子句的末尾。这意味着:“到目前为止,我接受了这个程序中的第一个解决方案,我不想从这里回去寻找任何其他解决方案”。该条款将更改为:

if((X-Y), Iresult, Entry) :-
    X > Y,
    Iresult is Entry,
    !.

但是......这在小程序中很好,如果您确实需要在程序的其他部分进行回溯,这可能会破坏它。更简洁的方法是检查两个子句中的适当条件。将它们重写为:

if((X-Y), Iresult, Entry) :-
    X > Y,                                           
    Iresult is Entry.

if((X-Y), Iresult, _) :-
    X =< Y,
    Iresult is 0.

然后你确定如果 X>Y,第二个子句将失败。

在这些修改之后,您的代码应该可以工作......如果没有,请报告。尽管如此,它仍然不会很序幕。这有点太冗长了。


编辑:

好的,我会以一种简单的方式编写它:

sum_if_bigger([], [], 0).
sum_if_bigger([A|L1], [B|L2], Result) :-
        sum_if_bigger(L1, L2, Partial),
        Result is Partial + max(0, A-B).

...或以尾递归方式:

sum_if_bigger_tr(L1, L2, R) :-
        sum_if_bigger_tr(L1, L2, 0, R).
sum_if_bigger_tr([], [], R, R).
sum_if_bigger_tr([A|L1], [B|L2], Partial, Result) :-
        NewPartial is Partial + max(0, A-B),
        sum_if_bigger_tr(L1, L2, NewPartial, Result).
于 2009-11-20T01:52:55.037 回答