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, N, [[X,N]]) :- basicpart(X).
partsof(X, N, P) :-
	assembly(X, Subparts),
	partsoflist(N,Subparts, P).

partsoflist(_, [], []).
partsoflist(M,[quant(X, N) | Tail], Total) :-
	K is M * N,
	partsof(X, K,  HeadParts),
	partsoflist(M, Tail, TailParts),
	append(HeadParts, TailParts, Total).

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