% File 'prolog_meta.pl'
%----
:- import(prolog_types).

%%% rk: principle construction of meta_types:
%%% :- type meta(Apply_Kind(Typepars) of Meta_Kind).
%%% Apply_Kind --> trmName; trmFull.
%%% Meta_Kind  --> mpred; mfunc; mtype(TargetType); mall.
%%% Typepar(s) --> type-parameter(s) of predicate- or function-declaration
%%% TargetType --> target-type of function-declaration
%%% The giving of Apply_Kind, Meta_Kind or Typepar(s) is optional.
%%% The of-operator is necessary, if Apply_Kind and Meta_Kind are given.

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

% The syntactic kernel of Prolog  (and StdP)
:- pred {goal :- goal}.         %  e.g., used in assert((head:-body))
:- pred {:- goal}.              %  e.g., used in transform/4 %%% rk
:- pred {?- goal}.              %  e.g., used in transform/4 %%% rk
:- pred {goal,goal}.            %  , = conjunction     
:- pred {goal;goal}.            %  ; = disjunction
:- pred {goal->goal}.           %  -> = if-then
:- pred !.
:- pred \+ goal.
:- pred not(goal).




:- type clause_term == goal.

:- type goal > simpleterm.

:- pred clause(goal, goal).		% StdP
:- pred call(goal).			% StdP
:- pred once(goal).			% StdP
:- pred top^goal.
:- pred assert(meta(mclause)).                 %%%rk: new type (meta2)
:- pred asserta(meta(mclause)).		% StdP %%%rk: new type (meta2)
:- pred assertz(meta(mclause)).		% StdP %%%rk: new type (meta2)
:- pred retract(meta(mclause)).		% StdP
:- pred retractall(goal).

:- pred current_predicate(aritypredname).		% StdP

%:- type term.
%:- type term > atom.
%:- type term > atomic.
%:- type term > compound.
%:- type term > simpleterm.

:- type atomic > atom.

%:- type term == top.
:- type simpleterm --> {X | simple(X)}.
%:- type term --> {X | (simple(X); compound(X))}.
:- type atom --> {X | atom(X)}.
%:- type atom == top.
:- type atomic --> {X | atomic(X)}.
%:- type atomic == top.
%:- type compound_term --> {X | compound(X)}.
:- type compound_term == top.

:- type boolean --> true; false.
:- type atom > boolean.
:- type goal > boolean.

:- pred abolish(aritypredname).                 % StdP

:- pred top =.. list(top).			% StdP
:- pred functor(term,atomic,nat).		% StdP
:- pred arg(nat,compound_term,term).		% StdP
:- pred copy_term(term,term).	          	% StdP




:- pred bagof(Term, goal, list(@Term)).	% StdP
:- pred setof(Term, goal, list(@Term)).		% StdP
:- pred findall(Term, goal, list(@Term)).		% StdP


:- pred var(top).		% StdP
:- pred nonvar(term).		% StdP
:- pred ground(top).
:- pred atom(term).		% StdP
:- pred atomic(term).		% StdP
:- pred compound(term).		% StdP

:- pred simple(top).

:- pred name(top,list(top)).
:- pred numbervars(top,nat,nat).

:- pred subsumes_chk(top,top).

:- pred expand_term(term,term).
:- pred term_expansion(term, term).

:- pred callable(top).

% other commonly uses predicates

:- pred number_chars(num,list(_Char)).		% StdP
:- pred number_codes(num,list(char_code)).	% StdP
:- pred atom_chars(atom,list(_Char)).		% StdP
:- pred atom_codes(atom,list(_CharCode)).	% StdP
:- pred atom_concat(atom,atom,atom).		% StdP
:- pred atom_length(atom,nat).			% StdP




%%--------------

% special types for Typical

:- type big_typename.  %%%
:- type big_typename > modtypename.
:- type big_typename > simpletypename.

:- type typename == simpletypename.
:- type simpletypename --> {X|simple(X)}.        % A kind of hack!
:- type simpletypename > atomic.

:- type modtypename --> filename:typename.
:- type modtypename > simpletypename.


%---------

:- type big_predname.  %%%
:- type big_predname > modpredname.
:- type big_predname > aritypredname.
:- type big_predname > simplepredname.

:- type predname == simplepredname.

:- type simplepredname --> {X|simple(X)}.        % A kind of hack!
:- type simplepredname > atomic.

:- type aritypredname --> simplepredname/nat.

:- type modpredname --> filename:aritypredname.
:- type modpredname > aritypredname.



%--------


:- type filename == atom.

%---------

:- pred fcall(meta((trmFull([]) of mpred))).
:- pred fcall(meta((trmName([T]) of mpred)), T).
:- pred fcall(meta((trmName([T1,T2]) of mpred)), T1, T2).
:- pred fcall(meta((trmName([T1,T2,T3]) of mpred)), T1, T2, T3).
:- pred fcall(meta((trmName([T1,T2,T3,T4]) of mpred)), T1,T2,T3,T4).
:- pred fcall(meta((trmName([T1,T2,T3,T4,T5]) of mpred)), T1,T2,T3,T4,T5).
:- pred fcall(meta((trmName([T1,T2,T3,T4,T5,T6]) of mpred)), T1,T2,T3,T4,T5,T6).
:- pred fcall(meta((trmName([T1,T2,T3,T4,T5,T6,T7]) of mpred)), 
                T1,T2,T3,T4,T5,T6,T7).
:- pred fcall(meta((trmName([T1,T2,T3,T4,T5,T6,T7,T8]) of mpred)), 
                T1,T2,T3,T4,T5,T6,T7,T8).
:- pred fcall(meta((trmName([T1,T2,T3,T4,T5,T6,T7,T8,T9]) of mpred)), 
                T1,T2,T3,T4,T5,T6,T7,T8,T9).
:- pred fcall(meta((trmName([T1,T2,T3,T4,T5,T6,T7,T8,T9,TA]) of mpred)), 
                T1,T2,T3,T4,T5,T6,T7,T8,T9,TA).

:- pred flcall(meta((trmName of mpred)), list(T)).

