计算嵌套列表中不是原子的项数
Count the number of terms that are not atoms in a nested list
我有这些事实:
vehicle(car,blue,[wheel,horn,optional(radio)]).
vehicle(motorcycle,blue,[wheel,optional(navigation),horn]).
vehicle(truck,white,[wheel,horn,optional(trailer)]).
我想计算所有蓝色车辆的所有可选项目(所有“可选”) - 在本例中为 2。
现在我有一个谓词创建一个嵌套列表,其中包含所有蓝色车辆的组件列表:
countAllOptionalComponents:-
findall(X,vehicle(_,blue,X),S),
write(S).
[[轮子,喇叭,可选(收音机)],[轮子,可选(导航),喇叭]]
我的想法是将这个嵌套列表传递给另一个谓词以计算所有“子列表”的所有可选组件,但我遇到了麻烦。像这样:
countAllOptionalComponents:-
findall(X,vehicle(_,blue,X),S),
countOptComponents(S,N).
countOptComponents([],0).
countOptComponents([X,Y],N):-
[...]
也许我遵循的方法没有多大意义。
一种可能的解决方案如下:
count(C) :-
findall(X, vehicle(_, blue, X), Ls),
countOpt(Ls, 0, C).
countOpt([], X, X) :- !.
countOpt([H|T], C, NewC) :-
countOpt(T, C, NewC1),
findall(Opt, member(optional(Opt), H), Opts),
printOpts(Opts),
length(Opts, Length),
NewC is NewC1 + Length, !.
printOpts([]).
printOpts([H|T]) :-
print(H),
nl,
printOpts(T).
按照您的方法,首先收集每辆车的所有特征列表(我猜?)并将其保存在名为 Ls
的列表列表中。
然后 select 在 Ls
的每个子列表中的所有可选值 (Opt
) 并添加它们的所有长度。
我还添加了谓词来打印结果。
如果您已经在使用 findall()
并且您知道通过将 findall 包装在 () 中间可以有多个目标,那么您可以在其中放置另一个 findall:
countAllOptionalComponents(OptionCount) :-
findall(CarOptions,
(vehicle(_, blue, CarAllItems),
findall(O, member(optional(O), CarAllItems), CarOptions)
), AllOptionsNested),
append(AllOptionsNested, AllOptions),
write(AllOptions),
length(AllOptions, OptionCount).
append/2 扁平化嵌套列表,append([[horn], [radio,aircon]], [horn,radio,aircon])
.
我有这些事实:
vehicle(car,blue,[wheel,horn,optional(radio)]).
vehicle(motorcycle,blue,[wheel,optional(navigation),horn]).
vehicle(truck,white,[wheel,horn,optional(trailer)]).
我想计算所有蓝色车辆的所有可选项目(所有“可选”) - 在本例中为 2。 现在我有一个谓词创建一个嵌套列表,其中包含所有蓝色车辆的组件列表:
countAllOptionalComponents:-
findall(X,vehicle(_,blue,X),S),
write(S).
[[轮子,喇叭,可选(收音机)],[轮子,可选(导航),喇叭]]
我的想法是将这个嵌套列表传递给另一个谓词以计算所有“子列表”的所有可选组件,但我遇到了麻烦。像这样:
countAllOptionalComponents:-
findall(X,vehicle(_,blue,X),S),
countOptComponents(S,N).
countOptComponents([],0).
countOptComponents([X,Y],N):-
[...]
也许我遵循的方法没有多大意义。
一种可能的解决方案如下:
count(C) :-
findall(X, vehicle(_, blue, X), Ls),
countOpt(Ls, 0, C).
countOpt([], X, X) :- !.
countOpt([H|T], C, NewC) :-
countOpt(T, C, NewC1),
findall(Opt, member(optional(Opt), H), Opts),
printOpts(Opts),
length(Opts, Length),
NewC is NewC1 + Length, !.
printOpts([]).
printOpts([H|T]) :-
print(H),
nl,
printOpts(T).
按照您的方法,首先收集每辆车的所有特征列表(我猜?)并将其保存在名为 Ls
的列表列表中。
然后 select 在 Ls
的每个子列表中的所有可选值 (Opt
) 并添加它们的所有长度。
我还添加了谓词来打印结果。
如果您已经在使用 findall()
并且您知道通过将 findall 包装在 () 中间可以有多个目标,那么您可以在其中放置另一个 findall:
countAllOptionalComponents(OptionCount) :-
findall(CarOptions,
(vehicle(_, blue, CarAllItems),
findall(O, member(optional(O), CarAllItems), CarOptions)
), AllOptionsNested),
append(AllOptionsNested, AllOptions),
write(AllOptions),
length(AllOptions, OptionCount).
append/2 扁平化嵌套列表,append([[horn], [radio,aircon]], [horn,radio,aircon])
.