% dynamiek rulez

:- dynamic(item/8).
:- dynamic(sentence_size/1).
:- dynamic(sentence_word/2).

is_preterminal(X) :- word(_, X).
is_nonterminal(X) :- rule(X, _).
is_nonpreterminal(X) :- not(is_preterminal(X)).
is_word(X) :- word(X, _).



%%% de regels %%%

rule(s, [ [np, vp], [aux, np, vp], [vp] ]).
rule(np, [ [det, nominal], [proper_noun] ]).
rule(vp, [ [verb], [verb, np] ]).
rule(nominal, [ [noun], [noun, nominal], [nominal, pp] ]).
rule(pp, [ [prep, np] ]).

word(that, det).
word(this, det).
word(a, det).
word(book, noun).
word(flight, noun).
word(meal, noun).
word(money, noun).
word(book, verb).
word(include, verb).
word(prefer, verb).
word(does, aux).
word(from, prep).
word(to, prep).
word(on, prep).
word(houston, proper_noun).
word(twa, proper_noun).



%%% de parser %%%

create_item(LHS, RHSOLD, RHS, BEGIN, CHART, L, _) :-
	item(_, LHS, RHSOLD, RHS, BEGIN, CHART, L, _), !.
create_item(LHS, RHSOLD, RHS, BEGIN, CHART, L, CREATOR) :-
	gensym(s, P),
	assertz(item(P, LHS, RHSOLD, RHS, BEGIN, CHART, L, CREATOR)), !.

retract_all :-
	retract_all_items,
	retract_all_words.

retract_all_items :-
	item(POINTER, LHS, RHSOLD, RHS, BEGIN, CHART, LIST, CREATOR),
	retract(item(POINTER, LHS, RHSOLD, RHS, BEGIN, CHART, LIST, CREATOR)),
	fail.
retract_all_items.

retract_all_words :-
	sentence_word(A, B),
	retract(sentence_word(A, B)),
	fail.
retract_all_words :-
	sentence_size(X),
	retract(sentence_size(X)).
retract_all_words.

create_words([], N) :-
	assertz(sentence_size(N)).
create_words([H|T], N) :-
	assertz(sentence_word(N, H)),
	M is N+1,
	create_words(T, M).

earley_parse(L) :-
	retract_all,
	create_words(L, 0), 
	create_item(gamma, [], [s], 0, 0, [], seed),
	apply_loop,
	!,
	sentence_size(X),
	item(_, gamma, _, [], 0, X, _, _).

number_of_items(N) :-
	findall(X, get_item(X), L),
	listlen(L, N).

get_item(X) :-
	item(POINTER, LHS, RHSOLD, RHS, BEGIN, CHART, LIST, CREATOR),
	X = item(POINTER, LHS, RHSOLD, RHS, BEGIN, CHART, LIST, CREATOR).
	
listlen([],0).
listlen([_|T], N) :- listlen(T, N1), N is N1 + 1.

apply_loop :-
	repeat,
	number_of_items(N),
	apply_operators,
	number_of_items(M),
	D is N - M,
	D = 0.

apply_operators :-
	item(POINTER, LHS, RHSOLD, RHS, BEGIN, CHART, LIST, CREATOR),
	do_operator(item(POINTER, LHS, RHSOLD, RHS, BEGIN, CHART, LIST, CREATOR)),
	fail.
apply_operators.

do_operator(item(P, LHS, RHSOLD, [RHSH|RHST], BEGIN, CHART, L, C)) :-
	is_nonpreterminal(RHSH),
	predictor(item(P, LHS, RHSOLD, [RHSH|RHST], BEGIN, CHART, L, C)).

do_operator(item(P, LHS, RHSOLD, [RHSH|RHST], BEGIN, CHART, L, C)) :-
	is_preterminal(RHSH),
	scanner(item(P, LHS, RHSOLD, [RHSH|RHST], BEGIN, CHART, L, C)).

do_operator(item(P, LHS, RHSOLD, [], BEGIN, CHART, L, C)) :-
	completer(item(P, LHS, RHSOLD, [], BEGIN, CHART, L, C)).

predictor_creator(_, _, [], _, _, _, _, _).
predictor_creator(LHS, [RHSH|RHST], BEGIN, CHART, L, C) :-
	create_item(LHS, [], RHSH, BEGIN, CHART, L, C),
	predictor_creator(LHS, RHST, BEGIN, CHART, L, C). 

predictor(item(_, _, _, [RHSH|_], _, CHART, _, _)) :-
	rule(RHSH, ALT),
	predictor_creator(RHSH, ALT, CHART, CHART, [], predictor). 

scanner(item(_, _, _, [RHSH|_], _, CHART, _, _)) :-
	sentence_word(CHART, WORD),
	word(WORD, RHSH),
	NEXT_CHART is CHART + 1,
	create_item(RHSH, [WORD], [], CHART, NEXT_CHART, [], scanner).
scanner(_).

completer(item(P, LHS, _, [], BEGIN, CHART, _, _)) :-
	item(_, A, RHSOLD, [LHS|T], I, BEGIN, L, _),
	append(RHSOLD, [LHS], NEWRHSOLD),
	append(L, [P], NEWL),
	create_item(A, NEWRHSOLD, T, I, CHART, NEWL, completer),
	fail.
completer(_).
