Ontospec example
authordgarijo
Tue, 06 Mar 2012 19:18:31 +0100
changeset 1779 d9433150115d
parent 1778 cb6d3fd66bee
child 1781 d77f989a6b9c
Ontospec example
ontology/DocExamples/Ontospec/onto_spec.pl
ontology/DocExamples/Ontospec/spec.html
--- /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.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ontology/DocExamples/Ontospec/spec.html	Tue Mar 06 19:18:31 2012 +0100
@@ -0,0 +1,15 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+<link rel="meta" type="application/rdf+xml" title="FOAF" href="http://moustaki.org/foaf.rdf" />
+ <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+<meta name="author" content="Yves Raimond" />
+<meta name="robots" content="all" />
+<title>Yves Raimond</title>
+</head>
+<body><div class="glance" id="glance" style="padding: 5px; border: dotted; background-color: #ddd;">
+<p>Classes: |  </p>
+<p>Properties: | </p>
+<p>Individuals: |  </p></div>
+<h3>Classes and Properties (full detail)</h3>
+</body></html>
\ No newline at end of file