Rekursion uppstår när någonting definieras i termer av sig själv.

Dagens rekursion

% state(RobotPosition, HeldItems, R1Items, R2Items, R3Items)

% pickup(State, Item) -> NewState, Action
pickup(state(room1, Held, R1, R2, R3), Item, NewState, TheAction) :-
	member(Item, R1),
	length(Held, HeldCount),
	HeldCount < 2,
	delete(R1, Item, NewR1),
	append(Held, [Item], NewHeld),
	NewState = state(room1, NewHeld, NewR1, R2, R3),
	TheAction = pickup(Item).

pickup(state(room2, Held, R1, R2, R3), Item, NewState, TheAction) :-
	member(Item, R2),
	length(Held, HeldCount),
	HeldCount < 2,
	delete(R2, Item, NewR2),
	append(Held, [Item], NewHeld),
	NewState = state(room2, NewHeld, R1, NewR2, R3),
	TheAction = pickup(Item).

pickup(state(room3, Held, R1, R2, R3), Item, NewState, TheAction) :-
	member(Item, R3),
	length(Held, HeldCount),
	HeldCount < 2,
	delete(R3, Item, NewR3),
	append(Held, [Item], NewHeld),
	NewState = state(room3, NewHeld, R1, R2, NewR3),
	TheAction = pickup(Item).

% drop(State, Item) -> NewState, Action
drop(state(room1, Held, R1, R2, R3), Item, NewState, TheAction) :-
	member(Item, Held),
	delete(Held, Item, NewHeld),
	append(R1, [Item], NewR1),
	NewState = state(room1, NewHeld, NewR1, R2, R3),
	TheAction = drop(Item).

drop(state(room2, Held, R1, R2, R3), Item, NewState, TheAction) :-
	member(Item, Held),
	delete(Held, Item, NewHeld),
	append(R2, [Item], NewR2),
	NewState = state(room2, NewHeld, R1, NewR2, R3),
	TheAction = drop(Item).

drop(state(room3, Held, R1, R2, R3), Item, NewState, TheAction) :-
	member(Item, Held),
	delete(Held, Item, NewHeld),
	append(R3, [Item], NewR3),
	NewState = state(room3, NewHeld, R1, R2, NewR3),
	TheAction = drop(Item).

% move(State, Room) -> NewState, Action
move(state(room1, Held, R1, R2, R3), room2, NewState, TheAction) :-
	member(steelkey, Held),
	NewState = state(room2, Held, R1, R2, R3),
	TheAction = move(room2).

move(state(room2, Held, R1, R2, R3), room1, NewState, TheAction) :-
	member(steelkey, Held),
	NewState = state(room1, Held, R1, R2, R3),
	TheAction = move(room1).


move(state(room1, Held, R1, R2, R3), room3, NewState, TheAction) :-
	member(brasskey, Held),
	NewState = state(room3, Held, R1, R2, R3),
	TheAction = move(room3).

move(state(room3, Held, R1, R2, R3), room1, NewState, TheAction) :-
	member(brasskey, Held),
	NewState = state(room1, Held, R1, R2, R3),
	TheAction = move(room1).


doSomething(State, NewState, TheAction) :-
	pickup(State, _, NewState, TheAction).
	
doSomething(State, NewState, TheAction) :-
	drop(State, _, NewState, TheAction).

doSomething(State, NewState, TheAction) :-
	move(State, _, NewState, TheAction).
	
solveR(State, Dest, _, []) :-
	State = Dest.

solveR(State, Dest, N, Trace) :-
	N > 0,
	doSomething(State, NewState, TheAction),
	N1 is N - 1,
	solveR(NewState, Dest, N1, TraceDown),
	Trace=[TheAction|TraceDown].

start(Trace) :-
	member(package, PackageList),
	solveR(
		state(room1, [], [steelkey], [brasskey], [package]),
		state(_, _, _, PackageList, _),
		12,
		Trace
	).

Gott & blandat