'Count the number of terms that are not atoms in a nested list
I have these facts:
vehicle(car,blue,[wheel,horn,optional(radio)]).
vehicle(motorcycle,blue,[wheel,optional(navigation),horn]).
vehicle(truck,white,[wheel,horn,optional(trailer)]).
I want to count all optional items (all "optional") of all blue vehicles - in this case 2. Right now I have a predicate that creates a nested list with the component lists of all blue vehicles:
countAllOptionalComponents:-
findall(X,vehicle(_,blue,X),S),
write(S).
[ [wheel,horn,optional(radio)], [wheel,optional(navigation),horn] ]
My idea was to pass this nested list to another predicate to count all optional components of all "sub-lists", but I'm having trouble. Something like this:
countAllOptionalComponents:-
findall(X,vehicle(_,blue,X),S),
countOptComponents(S,N).
countOptComponents([],0).
countOptComponents([X,Y],N):-
[...]
Maybe the approach I'm following doesn't make much sense.
Solution 1:[1]
If you are already using findall() and you know that there can be more than one goal in the middle of findall by wrapping it in () then you can put another findall in there:
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 flattens nested lists, append([[horn], [radio,aircon]], [horn,radio,aircon]).
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
