% Deutsche kontextfreie Grammatik - Tools
% Autor: Syntaxkurs 2013/2014
% Version 6

% Wrapper

check_grammar(Sentence) :-
    tokenize(Sentence, Tokens),
    s(Tokens, []).

generate_all(Tokens) :-
    s(Tokens,[]).

size(Count) :-
    aggregate_all(count, s(_,[]), Count).

run_tests :- tests.

% Utility functions

conforms(_,[]) :- !.

conforms([A|_], B) :-
    member(A,B), !.

conforms([_|L], B) :-
    conforms(L,B), !.

% Tester

tests :-
    positive(PositiveSentence),
    (
        check_grammar(PositiveSentence) ->
            write_succeed(PositiveSentence, '[TRUE POSITIVE] ')
        ;
        write_fail(PositiveSentence, '[FALSE NEGATIVE] ')
    ), fail.

tests :-
    negative(NegativeSentence),
    (
        not(check_grammar(NegativeSentence)) ->
            write_succeed(NegativeSentence, '[TRUE NEGATIVE] ')
        ;
        write_fail(NegativeSentence, '[FALSE POSITIVE] ')
    ), fail.

tests.

write_succeed(Sentence, Expected) :-
    string_to_list(String, Sentence),
    string_concat(Expected, String, Out),
    writeln(Out).

write_fail(Sentence, Expected) :-
    string_to_list(String, Sentence),
    string_concat(Expected, String, Out),
    writeln(Out).

% Tokenizer

tokenize(String, Tokens) :-

    phrase(data(Tokens), String), !.

data([A|As]) -->
    spaces(_),
    chars([X|Xs]),
    {atom_codes(A, [X|Xs])},
    spaces(_),
    data(As).
data([]) --> [].

chars([X|Xs]) --> char(X), !, chars(Xs).
chars([]) --> [].

spaces([X|Xs]) --> space(X), !, spaces(Xs).
spaces([]) --> [].

space(X) --> [X], {code_type(X, space)}.
char(X) --> [X], {\+ code_type(X, space)}.
