%==============================================================================
% Project:	Course "Logic Programming and deductive Databases"
% Version:	Summer 2017, University of Halle
% Module:	tp0.pl
% Purpose:	T_P-Operator (Meta-Interpreter for Bottom-Up Evaluation)
% Last Change:	02.06.2017
% Language:	LaTeX
% Authors:	Stefan Brass
% Email:	brass@informatik.uni-halle.de
% Address:	Universitaet Halle, Inst. f. Informatik, D-06099 Halle, Germany
% Copyright:	(c) 2017 by Stefan Brass
% Copying:	Do with it what you want, but do not make me responsible.
%		The code might contain bugs! There is no warranty.
%==============================================================================


%------------------------------------------------------------------------------
% Example data for given logic program:
%------------------------------------------------------------------------------

rule(p(X), [q(X), r3(X)], [var('X', X)]).
rule(q(X), [s(X)], [var('X', X)]).
rule(r3(X), [r2(X)], [var('X', X)]).
rule(r2(X), [r1(X)], [var('X', X)]).
rule(r1(b), [], []).
rule(s(a), [], []).
rule(s(b), [], []).

%------------------------------------------------------------------------------
% T_P Operator:
%------------------------------------------------------------------------------

derivable(Head, Facts) :-
	rule(Head, BodyList, _Vars),
	is_true(BodyList, Facts).

is_true([], _).
is_true([Lit|BodyRest], Facts) :-
	member(Lit, Facts),
	is_true(BodyRest, Facts).

tp(FactsIn, FactsOut) :-
	findall(Fact, derivable(Fact, FactsIn), FactsOut).

%------------------------------------------------------------------------------
% Iteration of T_P Operator:
%------------------------------------------------------------------------------

minmod(Facts) :-
	minmod_iter(0, [], Facts).

minmod_iter(N, Facts, MinMod) :-
	tp(Facts, NewFacts),
	(has_changed(Facts, NewFacts) ->
		NextN is N+1,
		minmod_iter(NextN, NewFacts, MinMod);
		MinMod = Facts).

has_changed(Facts, NewFacts) :-
	member(Fact, NewFacts),
	\+member(Fact, Facts).

