1

我对 Prolog 完全陌生,很难理解它的统一系统。我的问题如下:

我有一个约束整数、一个源数组和一个目标数组(它们都是整数数组)。我想过滤源数组中的元素,以便剩余元素在目标数组中具有对应的元素,以便源数组中的元素和目标数组中的元素之间的差异正好是约束。

示例:约束 = 1,源 = [1, 5, 7],目标 = [2, 3, 4]。FilteredSource 应该是 [1, 5],因为 abs(1 - 2) = 1 和 abs(5 - 4) = 1。Target 中没有 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
    ).

我很确定这是一个微不足道的问题,但我无法弄清楚,我正在拔掉头发。谢谢你的帮助!

4

1 回答 1

0

这应该工作

filterByDistanceConstraint(_Constraint, [], _Target, []).

filterByDistanceConstraint(Constraint, [SourceHead|SourceTail], Target, FilteredSource) :-
    (   passesDistanceConstraint(Constraint, SourceHead, Target)
    ->  FilteredSource = [SourceHead|NewFilteredSource]
    ;   FilteredSource = NewFilteredSource
    ),
    filterByDistanceConstraint(Constraint, SourceTail, Target, NewFilteredSource).

请注意第一个规则中的 [] 而不是 _,并且第二个规则中只有一个递归调用。

'filter' 编程模式在 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).
于 2014-11-03T06:34:20.120 回答