我有这个
initialstate(0,[],[[1,0],[2,3],[1,2],[2,3]]).
我想找到列表中的哪个子列表与数字1相同。 删除后排名第一的子列表。
会是这样的:
?- initialstate(_,_,[X,_]), initialstate(_,_,list),
delete(list,X,Newlist),assertz(initialstate(A,B,Newlist)).
我知道这是错的,但我想解释你想做什么。
我希望我的最终名单是:
initialstate(0,[],[[2,3],[2,3]]).
答案 0 :(得分:1)
编辑:在评论中纳入CapelliC对delete / 3和OP进一步查询的新答案。
谓词:
initial_state_without_elements(initialstate(A,B,List), Element,
initialstate(A,B,FilteredList) ):-
delete(List, Element, FilteredList).
查询:
?- initial_state_without_elements(initialstate(0,[],[[1,0],[2,3],[1,2],[2,3]]), [2,_], NewState).
NewState = initialstate(0, [], [[1, 0], [1, 2]]).
我们想要获取一些列表列表,ListOfLists,并删除包含给定Element的所有子列表Ls。通常,要检查元素X是否在某个列表List中,我们可以使用member(X, List)
。
所以我们想要一个列表列表,SubListsWithout,其中包含member(Element, SubList)
为假的所有List的ListOfLists。
这是一个谓词sublists_without_elements/3
,它将列表,元素和变量列表作为参数,并将变量与第一个不包含该元素的子列表列表统一起来。该谓词使用标准递归技术来描述列表:
sublists_without_element([], _, []).
sublists_without_element([L|Ls], Element, SubListsWithout) :-
member(Element, L), !,
sublists_without_element(Ls, Element, SubListsWithout).
sublists_without_element([L|Ls], Element, [L|SubListsWithout]) :-
sublists_without_element(Ls, Element, SubListsWithout).
第一个子句是我们的基本情况:空列表没有子列表,无论元素如何。
如果(1)Element是L的成员,则第二个子句为真,并且(2)SubListsWithout是Ls的子列表的列表,其不包含Element。 (注意:* L在这个子句中没有被添加到SubListsWithout中,这意味着它已被排除在我们正在积累的lits之外。!
用于修剪搜索路径,因为一旦我们知道了一个元素是L的成员,我们不想再与L有任何关系。)
如果将L添加到SubListsWithout,则第三个子句为true,而SubListsWithout包含Ls的其余子列表,这些子列表没有Element作为成员。
以上是编写自己的谓词来过滤列表的一种方法。重要的是,您能够编写和阅读此表单的谓词,因为您将看到大量的谓词。但是,您还需要了解Prolog实现的标准库。在SWI-Prolg中,您只需使用exclude\3
即可完成上述任务。因此,您可以通过以下方式实现您的预期目标:
filter_initial_state(initial_state(A,B,List),
Element,
initial_state(A,B,FilteredList)) :-
exclude(member(Element), List, FilteredList).
你可以这样使用它,
?- filter_initial_state(initial_state(0,[],[[1,0],[2,3],[1,2],[2,3]]), 1, Filtered).
和prolog将回复,
Filtered = initial_state(0, [], [[2, 3], [2, 3]]).
答案 1 :(得分:1)
我认为你选择了正确的内置(删除/ 3),但有一些细节错了。这是一个有效的'查询':
?- retract(initialstate(A,B,C)), C=[[X,_]|_], delete(C,[X,_],Newlist), assertz(initialstate(A,B,Newlist)).
A = 0,
B = [],
C = [[1, 0], [2, 3], [1, 2], [2, 3]],
X = 1,
Newlist = [[2, 3], [2, 3]].
首先:如果你在没有先撤回的情况下进行断言,那么你的数据几乎重复就会结束,而且可能不是你想要的。 assertz在之后存储更新的初始状态(有断言,但我怀疑会纠正错误)。
其次,请注意如何使用模式匹配来提取基本信息:
C=[[X,_]|_]
使用_(即匿名var)是必需的,因为允许指定我们在使用它时必须忽略的复杂结构的哪个部分。我们还必须使用它来表示删除/ 3 要匹配的。
delete(C,[X,_],Newlist)