我正在尝试定义谓词,在该谓词中搜索元素的列表列表并返回该元素的级别。例如,在搜索元素时:
?- elementLevel(element,[a,b,c,[d,e],[element,f]],Level).
Level = 2 .
因此,对于每个列表,它都会添加一个级别。我在考虑一个计数器,但我不知道如何为列表遍历实现它。
答案 0 :(得分:1)
我假设这是一个家庭作业,所以我会提供提示而不是代码。我希望这足以开发自己的代码,因为手头的任务只是中等复杂。
你需要一个事实和三个规则。
事实是忽略元素(即使用_
),用空列表统一列表,并说返回的级别为-1(未找到)。
第一个和第二个规则是“教科书”列表搜索,将元素与列表的头部统一,并返回级别1;另一条规则会忽略头部,并返回尾部元素的级别。
最终规则将使用嵌套的head和tail列表统一列表的头部,进行递归调用,并检查返回的值以查看它是否大于零。如果是,则返回值是嵌套返回加1;否则,递归检查尾部,并返回该检查的结果。
答案 1 :(得分:0)
你可以为计数器实现定义这样的谓词..
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).
答案 2 :(得分:0)
首先要注意的是,你的“列表列表”基本上是一个树结构,你基本上是对树进行深度优先,从左到右的遍历。
因此,您需要一个“公共”谓词,可以在树中搜索项目并返回其深度。回溯应该返回所有这样的匹配:
tree_walk( X , Tree , Depth ) :-
tree_walk( X , Tree , 0 , Depth ) % seed the accumulator with an initial depth
.
然后你需要工人谓词:
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
. %
这就是它的全部内容。
备注强>
要将其更改为广度优先搜索,我认为您需要做的就是颠倒工人谓词的最后两个子句的顺序。
如果X
未绑定或“列表列表”中的某个元素未绑定,您可能会遇到......有趣的问题。对于生产代码,您需要使用防护装置来妥善处理这些边缘情况。
干杯!
答案 3 :(得分:0)
我认为这是大多数方式......它不会返回例如。如果找不到元素,则返回-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, _, _).