--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ontology/DocExamples/Ontospec/onto_spec.pl Tue Mar 06 19:18:31 2012 +0100
@@ -0,0 +1,422 @@
+:- module(onto_spec,[op(200,fx,gen),gen/1,onto_spec/1,onto_spec_to_file/1]).
+
+
+/**
+ * This SWI-Prolog module allows to generate a
+ * HTML specification from the local RDF knowledge
+ * base.
+ *
+ * The output is similar to the specgen script used in
+ * the SIOC project.
+ *
+ * It handles rdfs:Class, rdf:Property, individuals, domain, range, domain-of, range-of,
+ * and also unionOf for domains and ranges
+ *
+ * Copyright Yves Raimond (c) 2007, Centre for Digital Music, Queen Mary, University of London
+ */
+
+:- use_module(library('semweb/rdf_db')).
+:- use_module(library('semweb/rdfs')).
+:- consult(library('semweb/rdf_http_plugin')).
+:- consult(library('semweb/rdf_turtle')).
+
+:- op(200,fx,gen).
+
+:- rdf_db:rdf_register_ns(dc,'http://purl.org/dc/elements/1.1/').
+:- rdf_db:rdf_register_ns(foaf,'http://xmlns.com/foaf/0.1/').
+:- rdf_db:rdf_register_ns(mo,'http://purl.org/ontology/mo/').
+:- rdf_db:rdf_register_ns(frbr,'http://purl.org/vocab/frbr/core#').
+:- rdf_db:rdf_register_ns(dcterms,'http://purl.org/dc/terms/').
+:- rdf_db:rdf_register_ns(event,'http://purl.org/NET/c4dm/event.owl#').
+:- rdf_db:rdf_register_ns(timeline,'http://purl.org/NET/c4dm/timeline.owl#').
+:- rdf_db:rdf_register_ns(time,'http://www.w3.org/2006/time#').
+:- rdf_db:rdf_register_ns(vs,'http://www.w3.org/2003/06/sw-vocab-status/ns#').
+:- rdf_db:rdf_register_ns(geo,'http://www.w3.org/2003/01/geo/wgs84_pos#').
+:- rdf_db:rdf_register_ns(af,'http://purl.org/ontology/af/').
+
+
+/**
+ * Top-level predicates:
+ * generate a HTML specification of the in-store schema
+ *
+ * onto_spec(-Spec)
+ */
+onto_spec(Spec) :-
+ header(Header),
+ tail(Tail),
+ glance_html_desc(Glance),
+ findall(NC-Desc,(class_html_desc(_:NC,Desc)),DescsMess),
+ keysort(DescsMess,Descs),
+ reverse(Descs,DescsR),
+ list_to_atom(DescsR,Classes),
+ findall(NP-Descp,prop_html_desc(_:NP,Descp),DescspMess),
+ keysort(DescspMess,Descsp),
+ reverse(Descsp,DescspR),
+ list_to_atom(DescspR,Properties),
+ findall(NI-Desci,(ind_html_desc(_:NI,Desci)),DescsiMess),
+ keysort(DescsiMess,Descsi),
+ reverse(Descsi,DescsiR),
+ list_to_atom(DescsiR,Individuals),
+ atom_concat(Header,Glance,T0),
+ atom_concat(T0,'\n<h3>Classes and Properties (full detail)</h3>\n',T1),
+ atom_concat(T1,Classes,T2),
+ atom_concat(T2,Properties,T3),
+ atom_concat(T3,Individuals,T4),
+ atom_concat(T4,Tail,Spec).
+
+header('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\n<head>\n<link rel="meta" type="application/rdf+xml" title="FOAF" href="http://moustaki.org/foaf.rdf" />\n <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />\n<meta name="author" content="Yves Raimond" />\n<meta name="robots" content="all" />\n<title>Yves Raimond</title>\n</head>\n<body>').
+
+tail('</body></html>').
+
+/**
+ * Outputs the specification to a file
+ */
+gen File :- onto_spec_to_file(File).
+onto_spec_to_file(File) :-
+ open(File,write,Stream,[]),
+ onto_spec(Spec),
+ write(Stream,Spec),
+ close(Stream).
+
+/**
+ * Wrappers for some simple rdf queries - plug your ontology language here:-)
+ */
+class_comment(NS:C,Comment) :-
+ class(Class),
+ rdf(Class,rdfs:comment,literal(Comment)),
+ rdf_global_id(NS:C,Class).
+class_status(NS:C,Status) :-
+ class(Class),
+ rdf(Class,vs:term_status,literal(Status)),
+ rdf_global_id(NS:C,Class).
+property_comment(NS:P,Comment) :-
+ property(Property),
+ rdf(Property,rdfs:comment,literal(Comment)),
+ rdf_global_id(NS:P,Property).
+property_status(NS:P,Status) :-
+ property(Property),
+ rdf(Property,vs:term_status,literal(Status)),
+ rdf_global_id(NS:P,Property).
+property_domain(NS:P,Domain) :-
+ rdf(Property,rdfs:domain,Domain),
+ \+bnode(Domain),
+ rdf_global_id(NS:P,Property).
+property_domain(NS:P,Domain) :-
+ rdf(Property,rdfs:domain,UnionOf),
+ rdf(UnionOf,rdf:type,owl:'Class'),
+ rdf(UnionOf,owl:unionOf,DomainList),
+ rdf_list_member(Domain,DomainList),
+ rdf_global_id(NS:P,Property).
+property_range(NS:P,Range) :-
+ rdf(Property,rdfs:range,Range),
+ \+bnode(Range),
+ rdf_global_id(NS:P,Property).
+property_range(NS:P,Range) :-
+ rdf(Property,rdfs:range,UnionOf),
+ rdf(UnionOf,rdf:type,owl:'Class'),
+ rdf(UnionOf,owl:unionOf,RangeList),
+ rdf_list_member(Range,RangeList),
+ rdf_global_id(NS:P,Property).
+property_inverse(NS:P,Inverse) :-
+ rdf(Property,owl:inverseOf,Inverse),
+ rdf_global_id(NS:P,Property).
+individual_title(NS:C,Title) :-
+ individual(I),
+ rdf(I,dc:title,literal(Title)),
+ rdf_global_id(NS:C,I).
+individual_description(NS:C,Desc) :-
+ individual(I),
+ rdf(I,dc:description,literal(Desc)),
+ rdf_global_id(NS:C,I).
+individual_class(NS:I,NS2:C) :-
+ individual(In),
+ class(Cl),
+ rdf(In,rdf:type,Cl),
+ rdf_global_id(NS:I,In),rdf_global_id(NS2:C,Cl).
+subclassof(C,C2) :-
+ rdf(C,rdfs:subClassOf,C2).
+class(Class) :-
+ rdf(Class,rdf:type,rdfs:'Class').
+individual(I) :-
+ rdf(I,rdf:type,C),class(C).
+property(Property) :-
+ rdf(Property,rdf:type,rdf:'Property').
+rdf_list_member(Member,List) :-
+ rdf(List,rdf:first,Member).
+rdf_list_member(Member,List) :-
+ rdf(List,rdf:rest,List2),
+ rdf_list_member(Member,List2).
+
+/**
+ * Spec At A Glance - FOAF/SIOC style
+ */
+glance_html_desc(Desc) :-
+ findall(C-CD,
+ (
+ class(Class),rdf_global_id(_:C,Class),
+ sformat(S1,
+ '<a href="#term_~w">~w</a> | ',
+ [C,C]
+ ),
+ string_to_atom(S1,CD)
+ ),
+ ClassesL),
+ keysort(ClassesL,ClassesLSorted),reverse(ClassesLSorted,ClassesLSR),
+ list_to_atom(ClassesLSR,Classes),
+ findall(P-PD,
+ (
+ property(Property),rdf_global_id(_:P,Property),
+ sformat(S2,
+ '<a href="#term_~w">~w</a> | \n',
+ [P,P]
+ ),
+ string_to_atom(S2,PD)
+ ),
+ PropertiesL),
+ keysort(PropertiesL,PropertiesLS),reverse(PropertiesLS,PropertiesLSR),
+ list_to_atom(PropertiesLSR,Properties),
+ findall(I-ID,
+ (
+ individual(Individual),rdf_global_id(_:I,Individual),
+ sformat(S3,
+ '<a href="#term_~w">~w</a> | \n',
+ [I,I]
+ ),
+ string_to_atom(S3,ID)
+ ),
+ IndividualsL),
+ keysort(IndividualsL,IndividualsLS),reverse(IndividualsLS,IndividualsLSR),
+ list_to_atom(IndividualsLSR,Individuals),
+ sformat(String,
+ '<div class="glance" id="glance" style="padding: 5px; border: dotted; background-color: #ddd;">\n<p>Classes: | ~w </p>\n<p>Properties: | ~w</p>\n<p>Individuals: | ~w </p></div>',
+ [Classes,Properties,Individuals]
+ ),
+ string_to_atom(String,Desc).
+
+
+/**
+ * HTML description of classes - FOAF/SIOC style
+ */
+class_html_desc(NS:C,HtmlDesc) :- %domain-of AND range-of available
+ class_comment(NS:C,Comment),
+ class_status(NS:C,Status),
+ sformat(StringHtml,
+ '<div class="specterm" id="term_~w"><h3>Class: ~w - ~w</h3>\n<em>~w</em>\n - ~w \n<br/>\n<p style="float: right; font-size: small;">[<a href="#glance">back to top</a>]</p>\n<br/>',
+ [C,NS:C,Status,C,Comment]
+ ),
+ string_to_atom(StringHtml,HtmlDesc1),
+ range_of_desc(NS:C,RangeOf),
+ domain_of_desc(NS:C,DomainOf),
+ subclass_of_desc(NS:C,SubClassOf),
+ sformat(StringAtt,
+ '\n<table style="th { float: top; }">~w\n~w\n~w</table>\n',
+ [RangeOf,DomainOf,SubClassOf]
+ ),
+ string_to_atom(StringAtt,Att),
+ atom_concat(Att,'\n</div>',Att2),
+ atom_concat(HtmlDesc1,Att2,HtmlDesc).
+
+range_of_desc(NS:C,'') :-
+ range_of_html_desc(NS:C,''),!.
+range_of_desc(NS:C,Desc) :-
+ range_of_html_desc(NS:C,RangeOf),
+ sformat(ROF,
+ '<tr><th>in-range-of:</th>~w</tr>\n',
+ [RangeOf]
+ ),
+ string_to_atom(ROF,Desc).
+
+domain_of_desc(NS:C,'') :-
+ domain_of_html_desc(NS:C,''),!.
+domain_of_desc(NS:C,Desc) :-
+ domain_of_html_desc(NS:C,DomainOf),
+ sformat(DOF,
+ '<tr><th>in-domain-of:</th>~w</tr>\n',
+ [DomainOf]
+ ),
+ string_to_atom(DOF,Desc).
+
+subclass_of_desc(NS:C,'') :-
+ subclass_of_html_desc(NS:C,''),!.
+subclass_of_desc(NS:C,Desc) :-
+ subclass_of_html_desc(NS:C,SubClassOf),
+ sformat(SOF,
+ '<tr><th>sub-class-of:</th>~w</tr>\n',
+ [SubClassOf]
+ ),
+ string_to_atom(SOF,Desc).
+
+/**
+ * HTML description of properties - FOAF/SIOC style
+ */
+prop_html_desc(NS:P,HtmlDesc) :-
+ property_comment(NS:P,Comment),
+ property_status(NS:P,Status),
+ sformat(StringHtmlComment,
+ '<div class="specterm" id="term_~w">\n<h3>Property: ~w - ~w</h3>\n<em>~w</em> - ~w \n<br/>',
+ [P,NS:P,Status,P,Comment]
+ ),
+ string_to_atom(StringHtmlComment,HtmlComment),
+ domain_html_desc(NS:P,DomainHtmlDesc),
+ range_html_desc(NS:P,RangeHtmlDesc),
+ inverse_html_desc(NS:P,InverseHtmlDesc),
+ sformat(StringHtmlDomainRange,
+ '<table style="th { float: top; }">\n<tr><th>Domain:</th>\n~w\n</tr>\n<tr><th>Range:</th>\n~w</tr>\n~w\n</table>\n<br/></div>',
+ [DomainHtmlDesc,RangeHtmlDesc,InverseHtmlDesc]
+ ),
+ string_to_atom(StringHtmlDomainRange,HtmlDomainRange),
+ atom_concat(HtmlComment,HtmlDomainRange,HtmlDesc).
+
+/**
+ * HTML description of individuals
+ */
+ind_html_desc(NS:I,HtmlDesc) :-
+ individual_title(NS:I,Title),
+ individual_description(NS:I,Description),
+ individual_class(NS:I,NS2:C),
+ sformat(S,
+ '<div class="specterm" id="term_~w">\n<h3>Individual: ~w</h3>\n<em>~w</em> - ~w \n<br/><table style="th { float: top; }"><tr><th>Class:</th>\n<td><a href="#term_~w">~w</a></td>\n</tr></table></div>',
+ [I,I,Title,Description,C,NS2:C]
+ ),
+ string_to_atom(S,HtmlDesc).
+
+/**
+ * HTML description of domains
+ */
+domain_html_desc(NS:P,DomainHtmlDesc) :-
+ property(Prop),rdf_global_id(NS:P,Prop),
+ findall(Html,(
+ property_domain(NS:P,Domain),
+ ((class(Domain),rdf_global_id(_:D,Domain),
+ sformat(S,
+ '<td><a href="#term_~w">~w</a></td>\n',
+ [D,D]),
+ string_to_atom(S,Html)
+ );
+ (\+class(Domain),rdf_global_id(NS2:D2,Domain),sformat(S,
+ '<td><a href="~w">~w</a></td>\n',
+ [Domain,NS2:D2])
+ )),
+ string_to_atom(S,Html)
+ ),Htmls),
+ list_to_atom(Htmls,DomainHtmlDesc).
+
+/**
+ * HTML description of range
+ */
+range_html_desc(NS:P,RangeHtmlDesc) :-
+ property(Prop),rdf_global_id(NS:P,Prop),
+ findall(Html,(
+ property_range(NS:P,Range),
+ ((class(Range),rdf_global_id(_:D,Range),
+ sformat(S,
+ '<td><a href="#term_~w">~w</a></td>\n',
+ [D,D]),
+ string_to_atom(S,Html)
+ );
+ (\+class(Range),rdf_global_id(NS2:D2,Range),sformat(S,
+ '<td><a href="~w">~w</a></td>\n',
+ [Range,NS2:D2])
+ )),
+ string_to_atom(S,Html)
+ ),Htmls),
+ list_to_atom(Htmls,RangeHtmlDesc).
+
+/**
+ * HTML description of inverse-of
+ */
+inverse_html_desc(NS:P,InverseHtmlDesc) :-
+ property(Prop),rdf_global_id(NS:P,Prop),
+ findall(Html,(
+ property_inverse(NS:P,Inverse),
+ ((class(Inverse),rdf_global_id(_:D,Inverse),
+ sformat(S,
+ '<td><a href="#term_~w">~w</a></td>\n',
+ [D,D]),
+ string_to_atom(S,Html)
+ );
+ (\+class(Inverse),rdf_global_id(NS2:D2,Inverse),sformat(S,
+ '<td><a href="~w">~w</a></td>\n',
+ [Inverse,NS2:D2])
+ )),
+ string_to_atom(S,Html)
+ ),Htmls),
+ list_to_atom(Htmls,InverseHtmlDesc2),
+ (InverseHtmlDesc2=''->InverseHtmlDesc='';(sformat(Temp,'<tr><th>Inverse-of: </th>~w</tr>',[InverseHtmlDesc2]),string_to_atom(Temp,InverseHtmlDesc))).
+
+/**
+ * HTML description of "domain of"
+ */
+domain_of_html_desc(NS:C,DomainOf) :-
+ class(Class),rdf_global_id(NS:C,Class),
+ findall(Html,(
+ property_domain(NS2:P,Class),rdf_global_id(NS2:P,_Property),
+ sformat(S,
+ '<td><a href="#term_~w">~w</a></td>\n',
+ [P,P]),
+ string_to_atom(S,Html)
+ ),Htmls),
+ list_to_atom(Htmls,DomainOf).
+
+/**
+ * HTML description of "range of"
+ */
+range_of_html_desc(NS:C,RangeOf) :-
+ class(Class),rdf_global_id(NS:C,Class),
+ findall(Html,(
+ property_range(NS2:P,Class),rdf_global_id(NS2:P,_Property),
+ sformat(S,
+ '<td><a href="#term_~w">~w</a></td>\n',
+ [P,P]),
+ string_to_atom(S,Html)
+ ),Htmls),
+ list_to_atom(Htmls,RangeOf).
+
+/**
+ * HTML description of "subclass of"
+ */
+subclass_of_html_desc(NS:C,SubClassDesc) :-
+ class(Class),rdf_global_id(NS:C,Class),
+ findall(Html,(
+ subclassof(Class,Class2),
+ ((class(Class2),rdf_global_id(_:D,Class2),
+ sformat(S,
+ '<td><a href="#term_~w">~w</a></td>\n',
+ [D,D]),
+ string_to_atom(S,Html)
+ );
+ (\+class(Class2),rdf_global_id(NS2:D2,Class2),sformat(S,
+ '<td><a href="~w">~w</a></td>\n',
+ [Class2,NS2:D2])
+ )),
+ string_to_atom(S,Html)
+ ),Htmls),
+ list_to_atom(Htmls,SubClassDesc).
+
+
+
+
+list_to_atom([],'').
+list_to_atom([_-A],A):-!.
+list_to_atom([A],A):-!.
+list_to_atom([_-H|T],At) :-
+ !,
+ list_to_atom(T,Temp),
+ atom_concat(Temp,H,At).
+list_to_atom([H|T],At) :-
+ list_to_atom(T,Temp),
+ atom_concat(Temp,H,At).
+
+
+bnode(B) :- atom_concat('__',_,B).
+
+
+
+
+:-
+ nl,
+ writeln(' Usage:'),
+ writeln(' - Load a RDF file using rdf_load/1'),
+ writeln(' - Generate the spec using ''gen ''spec.html'''''),
+ nl,nl.
+