:- ensure_loaded(common).
cvs_id('$Id: ontology_view.pl,v 1.5 2005/04/14 22:17:40 sandro Exp $').
/*

*/



tab(1000, Q, Focus, 'Ontology', +ontology_view(Q, Focus)) :-
	once(rdfq(Q, Focus, rdf:type, owl:'Ontology')).

tab(1000, Q, Focus, 'Property', +property_view(Q, Focus)) :-
	once(is_rdf_property(Q, Focus)).

property_view(Q, Focus, H) :-
	H=[+property_chart(Q, Focus)].

tab(1000, Q, Focus, 'Class', +class_view(Q, Focus)) :-
	once(is_rdf_class(Q, Focus)).

class_view(Q, Focus, H) :-
	H=[+class_chart(Q, Focus), +instances(Q, Focus)].

ontology_view(Q, Focus, H) :-
	address_latest_successful_ret(Focus, Ret),   %% wrong about redirects?!?!
	%  don't list out-of-namespace things for now...?
	setofsome(100, _,
		  Class,
		  (   ret_get(Ret, retr:chunk, Chunk),
		      pagein_graph(Chunk),
		      (   rdf(Class, rdf:type, rdfs:'Class', Chunk)
		      ;   rdf(Class, rdf:type, owl:'Class', Chunk)
		      ;   rdf(Class, rdfs:subClassOf, _, Chunk)
		      ;   rdf(_, rdfs:subClassOf, Class, Chunk)
		      ),
		      atom_prefix(Class, Focus)
		  ),
		  Classes),
	setofsome(100, _,
		  Property,
		  (   ret_get(Ret, retr:chunk, Chunk),
		      (   rdf(Property, rdf:type, rdf:'Property', Chunk)
		      ;   rdf(Property, rdf:type, owl:'Property', Chunk)
                      ;   rdf(Property, rdf:type, owl:'FunctionalProperty', Chunk)
		      ;   rdf(Property, rdf:type, owl:'InverseFunctionalProperty', Chunk)
		      ;   rdf(Property, rdf:type, owl:'DatatypeProperty', Chunk)
		      ;   rdf(Property, rdf:type, owl:'ObjectProperty', Chunk)
		      ;   rdf(Property, rdfs:subPropertyOf, _, Chunk)
		      ;   rdf(_, rdfs:subPropertyOf, Property, Chunk)
		      ),
		      atom_prefix(Property, Focus)
		  ),
		  Properties),
	H = [ table(tr(th('Class'), th('Description')),
		     +forall(  member(Class, Classes),
			       tr(td(+word(Q, Class)), td(+comment(Q, Class)))
			    ),
		    tr(th('Property'), th('Description')),
		     +forall(  member(Property, Properties),
			       tr(td(+word(Q, Property)), td(+comment(Q, Property)))
			    )
		    )
	    ].


same_property(_, X, X).
same_property(Q, X, Y) :-
	rdfq(Q, X, owl:sameAs, Y).
same_property(Q, X, Y) :-
	rdfq(Q, Y, owl:sameAs, X).
same_property(Q, X, Y) :-
	rdfq(Q, X, owl:samePropertyAs, Y).
same_property(Q, X, Y) :-
	rdfq(Q, Y, owl:samePropertyAs, X).

same_class(_, X, X).
same_class(Q, X, Y) :-
	rdfq(Q, X, owl:sameAs, Y).
same_class(Q, X, Y) :-
	rdfq(Q, Y, owl:sameAs, X).
same_class(Q, X, Y) :-
	rdfq(Q, X, owl:sameClassAs, Y).
same_class(Q, X, Y) :-
	rdfq(Q, Y, owl:sameClassAs, X).


%%    test this, then abstract/clean it a bit and make
%%    class_chart

%%   oops -- needs transitivity, etc!


property_chart(Q, Focus, H) :-
	setofsome(5, _, X,
		 same_property(Q, Focus, X),
		 SameList),
	setofsome(5, _, Y,
		 (   member(X, SameList),
		     rdfq(Q, X, rdfs:subPropertyOf, S),
		     same_property(Q, S, Y)
		 ), SuperList),
	setofsome(5, _, Y,
		 (   member(X, SameList),
		     rdfq(Q, S, rdfs:subPropertyOf, X),
		     same_property(Q, S, Y)
		 ), SubList),
	setofsome(5, _, Y,
		 (   member(X, SameList),
		     rdfq(Q, X, rdfs:domain, C),
		     same_class(Q, C, Y)
		 ), DomainList),
	setofsome(5, _, Y,
		 (   member(X, SameList),
		     rdfq(Q, X, rdfs:range, C),
		     same_class(Q, C, Y)
		 ), RangeList),
	setofsome(5, _, Y,
		 (   member(X, DomainList),
		     rdfq(Q, X, rdfs:subClassOf, C),
		     same_class(Q, C, Y)
		 ), SuperDomainList),
	setofsome(5, _, Y,
		 (   member(X, RangeList),
		     rdfq(Q, X, rdfs:subClassOf, C),
		     same_class(Q, C, Y)
		 ), SuperRangeList),
	setofsome(5, _, Y,
		 (   member(X, DomainList),
		     rdfq(Q, C, rdfs:subClassOf, X),
		     same_class(Q, C, Y)
		 ), SubDomainList),
	setofsome(5, _, Y,
		 (   member(X, RangeList),
		     rdfq(Q, C, rdfs:subClassOf, X),
		     same_class(Q, C, Y)
		 ), SubRangeList),
	!,
	H=div(h3('Partial Property Chart'),
	      table(class=ninechart, % border='2',
		    tr(th(' '), th('Domain'), th(' '), th('Range')),
		    tr(th('Super'),
		       td(+thing_list(Q, SuperDomainList)),
		       td(+thing_list(Q, SuperList)),
		       td(+thing_list(Q, SuperRangeList))),
		    tr(class=current, th('Current'),
		       td(+thing_list(Q, DomainList)),
		       td(class=chartFocus, p(class=label, 'Current Property:'), +thing_list(Q, SameList)),
		       td(+thing_list(Q, RangeList))),
		    tr(th('Sub'),
		       td(+thing_list(Q, SubDomainList)),
		       td(+thing_list(Q, SubList)),
		       td(+thing_list(Q, SubRangeList))))
		).

class_chart(Q, Focus, H) :-
	H=div(h3('Partial Class Chart'),
	      table(class=ninechart,
		    tr(th(' '), th('Is Range Of'), th(' '), th('is Domain Of'),
		    tr(th('Super'),
		       td(+related(Q, Focus, super, range)),
		       td(+related(Q, Focus, super, same)),
		       td(+related(Q, Focus, super, domain))
		      ),
		    tr(th(' '),
		       td(+related(Q, Focus, range, same)),
		       td(class=chartFocus, p(class=label, 'Current Subject:'), +related(Q, Focus, same, same)),
		       td(+related(Q, Focus, domain, same))
		      ),
		    tr(th('Sub'),
		       td(+related(Q, Focus, sub, range)),
		       td(+related(Q, Focus, sub, same)),
		       td(+related(Q, Focus, sub, domain))
		      )
		))).


instances(Q, Focus, H) :-
	setofsome(30, Done,
		  +word(Q, I),
		  rdfq(Q, I, rdf:type, Focus),
		  List),
	(   Done
	->  More = ''
	;   More = '...'
	),
	(   List = []
	->  H = h3('No Known Instances')
	;   H = [h3('Some Instances'), p(List), More]
	).

related(Q, Focus, P1, P2, [+thing_list(Q, List), More]) :-
	setofsome(8, Done,
		  E,
		  (   call_with_depth_limit((
					     rel(same, Focus, A, Q),
					     rel(P1, A, B, Q),
					     rel(same, B, C, Q),
					     rel(P2, C, D, Q),
					     rel(same, D, E, Q)
					    ), 6, _),
		      ground(E)    %   getting some var unixtime !?
		  ),
		  List),
	(   Done
	->  More = ''
	;   More = '...'
	).

% slightly lazy here, giving alternatives which don't make sense.  should be
% harmless...

%  DEPTH LIMIT NEEDED...

rel(super, Sub, Super, Q) :-
	rdfq(Q, Sub, rdfs:subClassOf, Super).
rel(super, Sub, Super, Q) :-
	rdfq(Q, Sub, rdfs:subPropertyOf, Super).
rel(super, Sub, Super, Q) :-
	rel(super, Sub, X, Q),
	rel(super, X, Super, Q).

rel(sub, Super, Sub, Q) :-
	rdfq(Q, Sub, rdfs:subClassOf, Super).
rel(sub, Super, Sub, Q) :-
	rdfq(Q, Sub, rdfs:subPropertyOf, Super).
rel(sub, Super, Sub, Q) :-
	rel(sub, Super, X, Q),
	rel(sub, X, Sub, Q).

rel(same, X, X, _Q).
rel(same, X, Y, Q) :-
	rdfq(Q, X, owl:sameAs, Y).
rel(same, X, Y, Q) :-
	rdfq(Q, Y, owl:sameAs, X).
rel(same, X, Y, Q) :-
	rdfq(Q, X, owl:samePropertyAs, Y).
rel(same, X, Y, Q) :-
	rdfq(Q, Y, owl:samePropertyAs, X).
rel(same, X, Y, Q) :-
	rdfq(Q, X, owl:sameClassAs, Y).
rel(same, X, Y, Q) :-
	rdfq(Q, Y, owl:sameClassAs, X).

rel(domain, X, Y, Q) :-
	rdfq(Q, X, rdfs:domain, Y).
rel(domain, Y, X, Q) :-
	rdfq(Q, X, rdfs:domain, Y).

rel(range, X, Y, Q) :-
	rdfq(Q, X, rdfs:range, Y).
rel(range, Y, X, Q) :-
	rdfq(Q, X, rdfs:range, Y).