我对Prolog来说是全新的,并且很难理解它的统一系统。我的问题如下:
我有一个Constraint整数,一个Source数组和一个Target数组(它们都是整数数组)。我希望过滤Source数组中的元素,以便其余元素在Target数组中具有对应元素,以便Source数组中的元素与Target数组中的元素之间的差异完全是Constraint。
示例:约束= 1,源= [1,5,7],目标= [2,3,4]。 FilteredSource应该是[1,5],因为abs(1 - 2)= 1而abs(5 - 4)= 1.目标中没有6或8,所以7不好。
根据我使用的参数,我得到错误的结果或查询得到无限循环。
到目前为止,我已经想出了这个:
filterByDistanceConstraint(_Constraint, [], _Target, _).
filterByDistanceConstraint(Constraint, [SourceHead|SourceTail], Target, FilteredSource) :-
filterByDistanceConstraint(Constraint, SourceTail, Target, NewFilteredSource),
(
passesDistanceConstraint(Constraint, SourceHead, Target)
->
append(NewFilteredSource, [SourceHead], FilteredSource),
filterByDistanceConstraint(Constraint, SourceTail, Target, NewFilteredSource)
;
filterByDistanceConstraint(Constraint, SourceTail, Target, FilteredSource)
).
passDistanceConstraint部分似乎工作正常,但我会在此处将其包含在内以供参考:
passesDistanceConstraint(_Constraint, _SourceHead, []) :-
fail.
passesDistanceConstraint(Constraint, SourceHead, [TargetHead|TargetTail]) :-
Distance is TargetHead - SourceHead,
( abs(Distance) =\= Constraint %test failed
-> passesDistanceConstraint(Constraint, SourceHead, TargetTail)
; write('Distance constraint passed for '), write(SourceHead), nl
).
我很确定这是一个微不足道的问题,但我无法解决这个问题,而且我会脱掉头发。谢谢你的帮助!
答案 0 :(得分:0)
这应该有效
filterByDistanceConstraint(_Constraint, [], _Target, []).
filterByDistanceConstraint(Constraint, [SourceHead|SourceTail], Target, FilteredSource) :-
( passesDistanceConstraint(Constraint, SourceHead, Target)
-> FilteredSource = [SourceHead|NewFilteredSource]
; FilteredSource = NewFilteredSource
),
filterByDistanceConstraint(Constraint, SourceTail, Target, NewFilteredSource).
注意第一个规则中的[]而不是_,并且第二个规则中只有一个递归调用。
'过滤器'编程模式在SWI-Prolog中通过include / 3或exclude / 3实现,但是用简单的Prolog编写,因为member / 2可以充当'枚举器':
filterByDistanceConstraint(Constraint, Source, Target, FilteredSource) :-
findall(E, (member(E, Source), member(C, Target), abs(E - C) =:= Constraint), FilteredSource).