%%% Kennissystemen assignment 1B.
%%% 0440949 Andreas van Cranenburgh
%%% 0435899 Niels Out
%%% 0512605 Stefan de Konink

:- consult(data).
:- consult(graph).

go1 :- 	writeln('Querying Wisdom Base for information on the enterprise (star trek) using the show predicate'),
	show(enterprise).
go2 :- 	writeln('Showing graphical classification of a Smart using XPCE'),
	true. %insert code here.

show(Name) :-        
	bagof(Property=Value, defined(Name, Property, Value), Specific),
	findall(X, classify(Name, [], X), Classification),
	findall(X=Y, numberrestriction(Name, X, Y), SNumRestr),	%note: we use findall so as not to fail
	findall(X, valuerestriction(Name, X), SValRestr),	%when there are no restrictions.
	hierarchy(CurrentNode, Name),
	findall(X, inherit(properties, Name, CurrentNode, [], X), IProperties),
	findall(X, inherit(numberrestrictions, Name, CurrentNode, [], X), INumRestr),
	findall(X, inherit(valuerestrictions, Name, CurrentNode, [], X), IValRestr),
	writeln('	classification: '), print2dhierarchy(Classification),
	writeln('	specific properties: '), printlist(Specific),
	writeln('	inherited properties: '), print3dlist(IProperties),
	writeln('	specific number restrictions: '), printlist(SNumRestr),
	writeln('	inherited number restrictions: '), print3dlist(INumRestr),
	writeln('	specific value restrictions: '), printlist(SValRestr),
	writeln('	inherited value restrictions: '), print3dlist(IValRestr).

%%% simple prety print
printlist([]).
printlist([H|List]) :-
	writeln(H),
	printlist(List).

%%% eg. [A,B,C] becomes: A --> B --> C
printhierarchy([H]) :- write(H), nl.
printhierarchy([H|List]) :-
	write(H), write('-->'),
	printhierarchy(List).

%%% call previous predicate for every list inside 2d list.
print2dhierarchy([]).
print2dhierarchy([H|List]) :-
	printhierarchy(H),
	print2dhierarchy(List).

%%% slightly less simple pretty print
print2dlist([]).
print2dlist([H|List]) :-
	printlist(H),
	print2dlist(List).

print3dlist([]).
print3dlist([H|List]) :-
	print2dlist(H),
	print3dlist(List).

%%% base case, get out of recursion, don't record properties of god.
inherit(_, _, god, List, List).

%%% %Inherit properties from parent types, collect properties and move
%%% up in the hierarcy.
inherit(properties, Name, CurrentNode, Accu, Answer) :-
	%%% fixme: maybe setof?? member check in accu?
        findall(CurrentNode:Property=Value, primitive(CurrentNode, Property, Value), List),
	hierarchy(NewNode, CurrentNode),
	inherit(properties, Name, NewNode, [List|Accu], Answer).

inherit(numberrestrictions, Name, CurrentNode, Accu, Answer) :-
	%%% fixme: maybe setof?? member check in accu?
        findall(CurrentNode:Restriction=Value, numberrestriction(CurrentNode, Restriction, Value), List),
	hierarchy(NewNode, CurrentNode),
	inherit(numberrestrictions, Name, NewNode, [List|Accu], Answer).

inherit(valuerestrictions, Name, CurrentNode, Accu, Answer) :-
	%%% fixme: maybe setof?? member check in accu?
        findall(CurrentNode:Restriction, valuerestriction(CurrentNode, Restriction), List),
	hierarchy(NewNode, CurrentNode),
	inherit(valuerestrictions, Name, NewNode, [List|Accu], Answer).

%classify(god, List, List).
%having god in the list shows the start of a path more clearly
classify(god, List, [god|List]).

classify(Name, Accu, Answer) :-
	hierarchy(CurrentNode, Name),
	classify(CurrentNode, [Name|Accu], Answer).
