List 序言列表搜索

List 序言列表搜索,list,prolog,List,Prolog,我试图定义一个谓词,它在列表中搜索一个元素并返回该元素的级别。例如,在搜索元素时: ?- elementLevel(element,[a,b,c,[d,e],[element,f]],Level). Level = 2 . 因此,对于每个列表,它都会添加一个级别。我正在考虑一个计数器,但我不知道如何实现列表遍历。我假设这是一个家庭作业,所以我会提供提示而不是代码。我希望这足以开发您自己的代码,因为手头的任务只相当复杂 你需要一个事实和三条规则 事实将忽略该元素(即使用\uu),将列表与空列表统

我试图定义一个谓词,它在列表中搜索一个元素并返回该元素的级别。例如,在搜索元素时:

?- elementLevel(element,[a,b,c,[d,e],[element,f]],Level).
Level = 2 .

因此,对于每个列表,它都会添加一个级别。我正在考虑一个计数器,但我不知道如何实现列表遍历。

我假设这是一个家庭作业,所以我会提供提示而不是代码。我希望这足以开发您自己的代码,因为手头的任务只相当复杂

你需要一个事实和三条规则

事实将忽略该元素(即使用
\uu
),将列表与空列表统一,并表示返回的级别为-1(未找到)

第一条和第二条规则是“教科书”列表搜索,将元素与列表头统一,并返回级别1;另一个规则将忽略头部,并返回尾部元素的级别


最后一条规则将把列表的头与头和尾的嵌套列表统一起来,进行递归调用,并检查返回值是否大于零。如果是,则返回值为嵌套返回加1;否则,递归检查尾部,并返回检查结果。

您可以为计数器实现定义这样的谓词

go:-  
ListLevel=0,  
NumberTobeFound=5,
go(List,NumberTobeFound,ItsLevel),  
write("Level",ItsLevel).

go([Head|Tail],NumberTobeFound,ItsLevel):-  
Head>NumberTobeFound,  
NewItsLevel=ItsLevel+1,  
go(Tail,NumberTobeFound,NewItsLevel).


go([Head|Tail],NumberTobeFound,ItsLevel):-  
Head<NumberTobeFound,  
NewItsLevel=ItsLevel+1,  
go(Tail,NumberTobeFound,NewItsLevel).

go([Head|Tail],NumberTobeFound,ItsLevel):-  
write("Number Found.."),  
write("Its Level is : ",ItsLevel).
go:-
ListLevel=0,
NumberTobeFound=5,
go(列表、编号、级别),
写入(“级别”,ITSLEEP)。
go([头|尾],编号Befound,其级别):-
Head>找到的编号,
新建ITS级别=ITS级别+1,
go(Tail、NumberTobeFound、NewItsLevel)。
go([头|尾],编号Befound,其级别):-

Head首先要注意的是,您的“列表列表”基本上是一个树结构,您基本上是在对树进行深度优先、从左到右的遍历

因此,您需要一个“public”谓词,它可以在树中搜索项并返回其深度。回溯应返回所有此类匹配:

tree_walk( X , Tree , Depth ) :-
  tree_walk( X , Tree , 0 , Depth ) % seed the accumulator with an initial depth
  .
然后您需要worker谓词:

tree_walk( X , [ X |  _ ] , D , D )    % success! if the desired item is found
  .                                    %
tree_walk( X , [ Y | Ys ] , T , D ) :- % otherwise...
  T1 is T+1 ,                          % - increment the depth
  tree_walk( X , Y , T1 , D )          % - and recurse down on the head of the list
  .                                    %
tree_walk( X , [ _ | Ys ] , T , D ) :- % if that failed, then
  tree_walk( X , Ys , T , D )          % - recursively search the tail of the list 
  .                                    %
这就是全部

注释

  • 要将其更改为广度优先搜索,我认为您所需要做的就是颠倒worker谓词最后两个子句的顺序

  • 如果
    X
    未绑定或“列表列表”中的一个元素未绑定,则可能会遇到……有趣的问题。对于生产代码,您需要设置防护装置,以正确处理这些边缘情况


干杯

我想这是最重要的。。如果没有找到元素,它不会返回例如-1,如果元素出现两次,它将报告错误的结果(即当元素找到时它不会停止)。它只显示了一个基本机制

% Base recursion / element found
elementLevel(element, element, 0).

% Any list with head and tail
elementLevel(element, [H|T], NestLevel) :-

    % Increment counter if H is a list/process possible sublists
    (is_list(H) ->
      elementLevel(element, H, NewLevel),
      elementLevel(element, T, NewLevel),
      NestLevel is NewLevel + 1  
    ;

    % No increments, just recurse through items
    elementLevel(element, H, NestLevel),
    elementLevel(element, T, NestLevel)
    ).

% Prevent empty sublists from causing a fail
elementLevel(element, _, _).

@换句话说,这是你给自己布置的家庭作业:)祝Prolog好运,这是一门迷人的小语言。