basicpart(rim).
basicpart(spoke).
basicpart(rearframe).
basicpart(handles).
basicpart(gears).
basicpart(bolt).
basicpart(nut).
basicpart(fork).

assembly(bike, [quant(wheel, 2), quant(frame, 1)]).
assembly(wheel, [quant(spoke, 20), quant(rim, 1), quant(hub, 1)]).
assembly(frame, [quant(rearframe, 1), quant(frontframe, 1)]).
assembly(frontframe, [quant(fork, 1), quant(handles, 1)]).
assembly(hub, [quant(gears, 1), quant(axle, 1)]).
assembly(axle, [quant(bolt, 1), quant(nut, 2)]).

partsof(X, [X]) :- basicpart(X).
partsof(X, P) :-
	assembly(X, Subparts),
	partsoflist(Subparts, P).

partsoflist([], []).
partsoflist([quant(X, N) | Tail], Total) :-
	partsof(X, HeadParts),
	partsoflist(Tail, TailParts),
	append(HeadParts, TailParts, Total).

append([], X, X).
append([A|B], X, [A|B1]) :- append(B, X, B1).
