temperature(thessaloniki,january,24,1).
temperature(thessaloniki,january,25,-2).
temperature(katerini,january,24,3).
temperature(loutsa,feb,25,1).
temp([],[],[]).
temp([H|T],L2,L3) :-
temp(T,L4,L5),
temperature(H,january,_,Te),
Te>0,
append([H],L4,L2),
L3=L5.
temp([H|T],L2,L3) :-
temp(T,L4,L5),
temperature(H,january,25,Te),
Te<0,
append([H],L5,L3),
L2=L4.
temp([H|T],L2,L3) :-
temp(T,L4,L5),
L2=L4,
L3=L5.
我们有温度和日期的城镇。我们需要将它们添加到正确的列表中。我认为规则是正确的,但是当我用TkEclipse运行时,我得到了这个:
?- temp([thessaloniki, thessaloniki, katerini, loutsa], L2, L3).
L2 = [thessaloniki, thessaloniki, katerini]
L3 = []
当我在程序示踪器上观看时只需要第一次temperature(thessaloniki,january,24,1).
2次而不是第二次temperature(thessaloniki,january,25,-2).
如果将第二个名称更改为thessaloniki2运行正常但是练习赋予它相同的名称。
答案 0 :(得分:3)
为什么您有一次目标temperature(H,january,_,Te)
和目标temperature(H,january,25,Te)
?我认为你的意思是两者都应该是同一个目标。
但还有其他风格的评论。我只是采取第一条规则:
temp([H|T],L2,L3) :- temp(T,L4,L5), temperature(H,january,_,Te), Te>0, append([H],L4,L2), L3=L5.
append/3
在Prolog中的使用量远低于您的预期。你可以用append([X],L4,L2)
逐字取代L2 = [X|L4]
。但你可以更进一步,将(=)/2
- 目标移到头上:
temp([H|T],[H|Ps],Ms) :- temp(T,Ps,Ms), temperature(H,january,_,Te), Te>0.
还不够:这样的程序会起作用,但会产生巨大的开销。参见:
在这种情况下,将有趣的测试移到顶部:
temp([H|T],[H|Ps],Ms) :- temperature(H,january,_,Te), Te>0, temp(T,Ps,Ms).
这将避免指数开销。 (第一个参数列表长度的指数)。
程序中的最后一条规则应该是:如果此城市没有数据,请忽略它。因此\+ temperature(H,january,_,_)
。
答案 1 :(得分:0)
因为您没有明确说明您的目标,所以我们会从代码段中猜测。我认为你错过了'过滤器'值:我将添加Mon,Day
来强制从声明的事实中进行适当的选择。
考虑使用可用的control predicates,并避免追加/ 3:
temperature(thessaloniki,january,24,1).
temperature(thessaloniki,january,25,-2).
temperature(katerini,january,24,3).
temperature(loutsa,feb,25,1).
temp([H|T], Mon, Day, L2, L3) :-
( temperature(H, Mon, Day, Te)
-> ( Te > 0
-> L2 = [H|L4], L3 = L5
; Te < 0
-> L2 = L4, L3 = [H|L5]
; L2 = L4, L3 = L5
)
; L2 = L4, L3 = L5
),
temp(T, Mon, Day, L4, L5).
temp([], _, _, [], []).
产量
?- temp([katerini, loutsa, thessaloniki],january,24,A,B).
A = [katerini, thessaloniki],
B = [].
?- temp([katerini, loutsa, thessaloniki],january,25,A,B).
A = [],
B = [thessaloniki].
注意如何避免追加/ 3:通过递归调用在“返回”的相应列表中构造列表consing
。感谢Prolog统一,即使呼叫“尚未到来”,我们也能做到。
我认为生成的代码是尾递归的,提高了效率。
HTH
编辑现在是等效的程序,但是(恕我直言)更好
temp([H|T], Mon, Day, L2, L3) :-
( temperature(H, Mon, Day, Te)
-> ( Te > 0
-> L2/L3 = [H|L4]/L5
; Te < 0
-> L2/L3 = L4/[H|L5]
; L2/L3 = L4/L5
)
; L2/L3 = L4/L5
),
temp(T, Mon, Day, L4, L5).
评论后编辑 ...
temp([H|T], L2, L3) :-
( temperature(H, january, Day, Te)
-> ( Te > 0
-> L2/L3 = [H|L4]/L5
; Te < 0, Day = 25
-> L2/L3 = L4/[H|L5]
; L2/L3 = L4/L5
)
; L2/L3 = L4/L5
),
temp(T, L4, L5).
temp([], [], []).
产量
A = [katerini, thessaloniki],
B = [].