% -*- prolog -*- 

% prime( +X ).

contains( FileName, Char ) :-
    seeing( Old ),
    see( FileName ),
    repeat, % cyklí až do řezu
        get_char( X ),
        ( X == end_of_file -> !, restore( Old ), fail
                            ; Char = X %, !, restore( Old )
        ).
restore( Old ) :- % obnov původní stream
    seen,
    see( Old ).

allchars( Filename, Chars ) :-
    setof( X, contains( Filename, X ), Chars ).

allchars_( Filename, Chars ) :-
    seeing( Old ),
    see( Filename ),
    fill_chars( [], Chars ),
    restore( Old ).
fill_chars( XS, Chars ) :-
    get_char( X ),
    ( X == end_of_file -> !, Chars = XS
                        ; fill_chars( [X|XS], Chars )
    ).



%%%%%%%%%%%%% gramatiky definitní klauzulí

% akceptuje/generuje mezeru
space --> " ".
space --> "\t".
space --> "\n".

% posloupnost mezer (i prázdná)
spaces --> [].
spaces --> space, spaces.

% trimujeme konec
trim_g_end( X ) --> spaces, \+ [_], !, {X = []}. % mezery až do konce --> fixujeme
                                                 % je třeba nastavit hlavu až po řezu
trim_g_end( [X|XS] ) --> [X], trim_g_end( XS ).

% gramatika pro trim
trim_g( XS ) --> space, !, trim_g( XS ). % fixujeme každou mezeru
trim_g( XS ) --> trim_g_end( XS ).

trim( List, TrimedList ) :- phrase( trim_g( TrimedList ), List ).

% ?- trim( " \naa\t ", X ), format( '|~s|', [X] ).
% |aa|









any_line --> any_not_newline, "\n".

any_not_newline --> [].
any_not_newline --> [Char], {[Char] \= "\n"}, any_not_newline.

any_lines --> [].
any_lines --> any_line, any_lines.

mhz_end( [] ) --> [].
mhz_end( [X|XS] ) --> [X], {code_type( X, digit )}, mhz_end( XS ).

mhz( [] ) --> [].
mhz( [X|XS] ) --> [X], {code_type( X, digit )}, mhz( XS ).
mhz( [X|XS] ) --> [X], {[X] = "."}, mhz_end( XS ).

cpu_mhz( X ) -->
    "cpu MHz", spaces, ":", spaces, mhz( X ), spaces, "\n".

proc_cpu( X ) --> cpu_mhz( X ), !, any_lines.
proc_cpu( X ) --> any_line, proc_cpu( X ).

freq( File, X ) :- phrase_from_file( proc_cpu( Y ), File ),
                   string_to_atom( Y, X ).

freq( X ) :- freq( "/proc/cpuinfo", X ).

%%%%%%%%%%%%%%%%%%%%% CLP

?- use_module( library( clpfd ) ).

mince( X ) :- X in 1 \/ 2 \/ 5 \/ 10 \/ 20 \/ 50.

zaplat( Castka, Mince ) :-
    zaplat_solve( Castka, Mince ), label( Mince ).

zaplat_solve( Castka, [Castka] ) :- mince( Castka ).
zaplat_solve( Castka, [M|MS] ) :-
    mince( M ),
    M #< Castka,
    Rem #= Castka - M,
    zaplat( Rem, MS ).

zaplat_solve3( Castka, MS ) :-
    seznam_minci( MS ),
    sum( MS, #=, Castka ).

seznam_minci( [] ).
seznam_minci( [M|MS] ) :- mince( M ), seznam_minci( MS ).

% chceme každé rozměnění jen jednou -> od největší mince
zaplat2( Castka, Mince ) :-
    zaplat_solve2( Castka, 50, Mince ), label( Mince ).

zaplat_solve2( Castka, MaxMince, [Castka] ) :-
    Castka #=< MaxMince, mince( Castka ).
zaplat_solve2( Castka, MaxMince, [M|MS] ) :-
    mince( M ),
    M #< Castka,
    M #=< MaxMince,
    Rem #= Castka - M,
    Rem #> 0,
    zaplat_solve2( Rem, M, MS ).

nonascending( [] ).
nonascending( [X|XS] ) :- nonascending( X, XS ).

nonascending( _, [] ).
nonascending( X, [Y|YS] ) :- X #>= Y, nonascending( Y, YS ).

zaplat3( Castka, Mince ) :-
    zaplat_solve( Castka, Mince ),
    nonascending( Mince ),
    label( Mince ).

% zaplat4( Castka, Mince ) :- Mince ins 

lp_mince( 50 ).
lp_mince( 20 ).
lp_mince( 10 ).
lp_mince( 5 ).
lp_mince( 2 ).
lp_mince( 1 ).

lp_zaplat( Castka, Mince ) :-
    lp_mince( Max ), !, lp_zaplat( Castka, Max, Mince ).

lp_zaplat( X, Max, [X] ) :- X =< Max, lp_mince( X ).
lp_zaplat( Castka, Max, [M|MS] ) :-
    lp_mince( M ),
    M =< Max,
    Rem is Castka - M,
    Rem >= 0,
    lp_zaplat( Rem, M, MS ).


%%%%%%%%%%%%%%%%%%%%%%
%
%
%
%
%
%
%
%

prime( X ) :- testPrime( 2, X ).

testPrime( P, P ) :- !. % zeleny rez
testPrime( D, P ) :-
    D < P, % zabezpeceni proti spatnemu pouziti
    P rem D =\= 0, % testujeme delitelnost
    D1 is D + 1,
    testPrime( D1, P ).
