%% exercise 1
edge(a,b).
edge(a,c).
edge(b,d).
edge(c,d).
edge(e,f).
edge(f,e).
target(d).
target(f).
reachable(a).
reachable(X) :- edge(Z,X), reachable(Z).
good(X) :- target(X), reachable(X).

%% exercise 2
move( state(left,P,open),
      go_right,
      state(right,P,open) ).
move( state(left,left,closed),
      opendoor,
      state(left,left,open) ).
move( state(P,P,S),
      pickup,
      state(P,robot,S) ).
move( state(P,robot,S),
      drop,
      state(P,P,S) ).

can_deliver( state(_,right,_), [] ).
can_deliver( OldState, [Action|Actions] ) :-
	move(OldState, Action, NewState),
	can_deliver(NewState, Actions).

%% exercise 3
bintree(leaf(X)) :-
	integer(X).
bintree(branch(Left,X,Right)) :-
	integer(X),
	bintree(Left),
	bintree(Right).

genbt(0,leaf(0)).
genbt(N,branch(Left,N,Left)) :-
	N1 is N - 1,
	genbt(N1,Left).

postorder_naive(leaf(X),[X]).
postorder_naive(branch(Left,X,Right),L) :-
	postorder_naive(Left,L1),
	postorder_naive(Right,L2),
	append(L1,L2,L3),
	append(L3,[X],L).

postorder_accu(T,L) :-
	postorder_accu(T,[],L).
postorder_accu(leaf(X),Acc,[X|Acc]).
postorder_accu(branch(Left,X,Right),Acc,L) :-
	postorder_accu(Right,[X|Acc],Acc1),
	postorder_accu(Left,Acc1,L).

test_tree( branch(branch(leaf(4),2,leaf(5)),1,branch(leaf(6),3,leaf(7))) ).

