%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Exercise 7.5, WS 2010/2011

drop(H,[H|T],T).
drop(H,[_|T],T1) :- drop(H,T,T1).


:- coinductive comember/2.
comember(X,L) :-  drop(X,L,L1), comember(X,L1).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% a)

stream(Stream) :- stream1(Stream), comember(0,Stream).


:- coinductive stream1/1.
stream1([0,E|Es]) :- even(E), stream1([E|Es]).
stream1([E|Es]) :- greater_zero(E), stream1(Es).


even(0).
even(s(s(X))) :- even(X).


greater_zero(s(0)).
greater_zero(s(X)) :- greater_zero(X).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% b)

automaton(Stream,S0) :- automaton1(Stream,S0,States), comember(s0,States).


:- coinductive automaton1/3.
automaton1([E|Stream],S0,States) :- trans(S0,E,S1), automaton1(Stream,S1,[S0|States]).


trans(s0,a,s1).
trans(s1,b,s0).
trans(s1,c,s2).
trans(s2,d,s1).




