获取列表中小于特定数字的所有元素

时间:2016-11-01 10:02:21

标签: prolog

当我正在学习Prolog时遇到了一个问题。我正在尝试制作这样的功能

   ?- less_than([1,2,3,2,1,5],3,Y).
      Y= [1,2,2,1]

因为我正在学习面向对象的编程,所以我堆积了这个并且无法弄清楚如何解决。 这是我的代码:

  less_than([],X,Y).
  less_than([H|T], X, [H1|T1]) :-
            H<X, less_than(T,X,H).

而且,我尝试使用findall:

  less_than([],X,Y).
  less_than([H|T],X,[H1|T1]) :-
            findall(H, (H<X, less_than(T,X,Y)), Z).

我得到了这个结果:

Y = [_G2274|_G2275]  for ?- less_than([1,2,3,4,5],3,X)

我知道它们是未知值但是如何在该列表中设置值?我试着用和H改变Y但是它不会工作。

我尝试调试它但没有成功,它一直在崩溃,这只是如何为我解决它的逻辑解释。 Any1有个主意吗?

1 个答案:

答案 0 :(得分:3)

我不会为你解决整个问题,但我想告诉你如何处理这些问题。

Prolog的一个主要优点是您可以调试声明性的问题。这意味着您使用Prolog的逻辑属性来查找意外答案的原因。

例如,在您的情况下,您有程序:

less_than([], X, Y).
less_than([H|T], X, [H1|T1]) :-
        H < X,
        less_than(T, X, H).

以及查询的以下非预期失败

?- less_than([1,2,3,2,1,5], 3, Y).
false.

让我们使用以下定义来概括一个Prolog程序,就像在GUPU中一样:

    cell.accessoryType = isChosen ? .checkmark : .none
    cell.leftMarginConstraint.constant = isChosen ? 40 : 0

例如,考虑以下概括,我们通过将:- op(920,fy, *). *_. 置于所有目标之前获得:

less_than([], X, Y).
less_than([H|T], X, [H1|T1]) :-
        * H < X,
        * less_than(T, X, H).

通过这种概括,我们有:

?- less_than([1,2,3,2,1,5],3,Y).
Y = [_G946|_G947].

所以,虽然现在一般,但至少查询成功

通过完善概括,我们可以缩小问题的确切原因。例如:

less_than([], X, Y).
less_than([H|T], X, [H1|T1]) :-
        * H < X,
        less_than(T, X, H).

这再次产生:

?- less_than([1,2,3,2,1,5],3,Y).
false.

观察添加更多目标最多可以专门化该程序,从不概括它。因此,如果我们希望此查询成功,则必须推广剩余的片段。

因此,如果您希望查询成功,则必须使至少以下片段成功进行查询:

less_than([], X, Y).
less_than([H|T], X, [H1|T1]) :-
        less_than(T, X, H).

为什么这会失败?请尝试以下进一步概括

less_than([], /*X*/_, /*Y*/_).
less_than([H|T], /*X*/_, [/*H1*/_|/*T1*/_]) :-
        less_than(T, /*X*/_, H).

仍然失败

?- less_than([1,2,3,2,1,5],3,Y).
false.

所以,我们现在减少到:

less_than([], _, _).
less_than([H|T], _, [_|_]) :-
        less_than(T, _, H).

现在重点:有趣的是,以下概括成功

less_than([], _, _).
less_than([H|T], _, [_|_]) :-
        less_than(T, _, /*H*/_).

因此,(*)/1召唤的最后一个论点是一个受到密切关注的热门候选人......