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.
One possible solution would be the following:
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).
As in your approach, first gather all lists of features (I guess?) for each vehicle and save it in a List of lists called Ls
.
Then select in each sublist of Ls
all Optional values (Opt
) and add all the lengths of them.
I also added the predicate to print the results.