Prolog中平方列表和子列表的二进制谓词

Prolog中平方列表和子列表的二进制谓词,prolog,Prolog,我不熟悉prolog,并且尝试创建一个二进制谓词,该谓词将 所有数字都是平方的列表,包括子列表中的数字。 e、 g 谁能指导我怎么做。 非常感谢。请使用代码片段回答。SWI Prolog具有谓词,允许您将谓词映射到某些列表。 使用它,你只需要做一个谓词,它将一个数字或列表中的数字平方,其他一切保持不变。如果谓词number/1的参数是数字或列表,则它们的参数is_list/1为真 因此: square(N,NN):- integer(N),

我不熟悉prolog,并且尝试创建一个二进制谓词,该谓词将 所有数字都是平方的列表,包括子列表中的数字。 e、 g

谁能指导我怎么做。
非常感谢。请使用代码片段回答。

SWI Prolog具有谓词,允许您将谓词映射到某些列表。 使用它,你只需要做一个谓词,它将一个数字或列表中的数字平方,其他一切保持不变。如果谓词number/1的参数是数字或列表,则它们的参数is_list/1为真

因此:

    square(N,NN):-
            integer(N),
            NN is N*N.

    square(L,LL):-
            is_list(L),
            dcountSublists(square,L,LL).

    square(Other,Other):-
            \+ number(Other),
            \+ is_list(Other).

    dcountSublists(L,LSquared):-
            maplist(square,L,LSquared).
使用最后一个谓词中的否定,我们可以避免多个(错误的)解决方案: 例如,
dcountsublist([2],X)
将返回
X=[4]
,否则返回
X=[2]
。 如果我们对square
使用if-then-else结构,或者使用once/1
调用
square/2
,就可以避免这种情况


如果这是作业,也许你不应该使用maplist,因为(可能)练习的目的是学习如何构建递归函数;在任何情况下,我都建议尝试编写一个没有maplist的等价谓词。

这很容易在Prolog中使用递归实现。请记住,Prolog中的所有内容都是一个变量或一个项(原子仅为0-arity项),因此如下所示:

[a,[[3]],b,4,c(5),4]
…很容易解构(还要注意,列表语法
[…]
是二进制谓词的糖)。Prolog还提供了一系列谓词来测试特定类型的术语,例如数字、字符串或复合术语(例如)

要构建您想要的谓词,我建议使用以下几种谓词编写它:

dcountSublists(In, Out) :-
  % analyze type of In
  % based on type, either: 
  %   1. split term into subterms for recursive processing
  %   2. term cannot be split; either replace it, or pass it through
下面是一个让你开始学习的例子,它做的很难。以下内容识别复合术语,并将其与术语de/constructor分开:

测试:

?- dcountSublists([a,[[e]],b,a,c(s),a], L).
L = [a, [[e]], b, a, c(s), a].
请注意,如果输入项有数字,则此操作将失败,因为它没有用于识别和处理数字的谓词。这件事由你决定

祝你好运

dcountSublists(In, Out) :-
  % test if In has type compound term
  compound(In),
  % cut to exclude backtracking to other cases below this predicate
  !, 
  % deconstruct In into functor and an argument list
  In =.. [Func|Args],
  % apply dcountSublists/2 to every argument, building new args
  maplist(dcountSublists, Args, NewArgs),
  % re-construct In using the new arguments
  Out =.. [Func|NewArgs].

dcountSublists(In, Out) :-
  % test if In has type atom
  atom(In), !, 
  % pass it through
  Out = In.
?- dcountSublists([a,[[e]],b,a,c(s),a], L).
L = [a, [[e]], b, a, c(s), a].