/*  $Id: owl2dig.pl, v 0.6.8 2005/4/12  zhisheng Exp $


    Author:        Zhisheng Huang, Willem Robert van Hage
    E-mail:        huang@cs.vu.nl
    WWW:           http://www.cs.vu.nl/~huang
    Copyright (C): 2004-2010 Vrije University Amsterdam

This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty
    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    As a special exception, if you link this library with other files,
    compiled with a Free Software compiler, to produce an executable, this
    library does not by itself cause the resulting executable to be covered
    by the GNU General Public License. This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.

*/

:- module(owl2dig,
	  [ owl2dig/2,				% +OWL, -DIG  with type: file(FileName), text(Text), elements(ElementList),  with a 'tell' header
	    owl_dig/2,				% +OWLElements, -DIGText,  without a header
          owl_dig_element/2,			% +OWLElement, -DIGText
          owl2dig_namespace_processing/2,	% +OWLElementsWithHeader, -OWLElementsWithoutHeader
          namespace_processing/1		% +NamespaceList
	  ]).


:-use_module(library('sgml')).
:-use_module(library('dig/dig_process')).


%basic owl2dig format

owl2dig(elements(L), text(Text)):-
     !,
      owl2dig_namespace_processing(L, L1),
	sformat(Text1, '<?xml version="1.0" encoding="UTF-8"?>', []),
      sformat(Text2, '<tells xmlns="http://dl.kr.org/dig/lang" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://wasp.cs.vu.nl/sekt/digtest/dig-1.1.xsd">', [ ]),
     	owl_dig(L1, Text3),
      sformat(Text4, '</tells> <!-- Created with OWL2DIG tool in the XDIG package 1.4.6 http://wasp.cs.vu.nl/sekt/dig -->', [ ]),
      undeclared_concepts(Cs),
      format_concepts(Cs, Text5),
      undeclared_roles(Rs),
      format_roles(Rs, Text6),
      retract_declaration_cache,
      concat_atom([Text1, Text2, Text5, Text6, Text3, Text4], Text),
	true.


owl2dig(file(InFile), file(OutFile)):-
      !,
	load_xml_file(InFile, L),
	owl2dig(elements(L), text(Text)),
      dig_file_out(OutFile, Text).

owl2dig(file(InFile), text(Text)):-
     !,
     load_xml_file(InFile, L),
     owl2dig(elements(L), text(Text)).


owl2dig(file(InFile), elements(L1)):-
     !,
     load_xml_file(InFile, L),
     owl2dig(elements(L), text(Text)),
     xmltext_elements(Text, L1).

owl2dig(text(Text1), file(OutFile)):-
     !,
     xmltext_elements(Text1, L),
     owl2dig(elements(L), text(Text2)),
     dig_file_out(OutFile, Text2),
     true.



owl2dig(text(Text1), text(Text2)):-
     !,
     xmltext_elements(Text1, L),
     owl2dig(elements(L), text(Text2)).

owl2dig(text(Text1), elements(L2)):-
     !,
     xml_elements(Text1, L, _),
     owl2dig(elements(L), text(Text2)),
     xmltext_elements(Text2, L2).


owl2dig(elements(L), file(OutFile)):-
     !,
     owl2dig(elements(L), text(Text)),
     dig_file_out(OutFile, Text).





owl2dig(elements(L), elements(L2)):-
     !,
     owl2dig(elements(L), text(Text)),
     xmltext_elements(Text, L2),
     true.


owl2dig(X, Y):-
    format('unknown owl2dig translation type: ~w, ~w~n', [X, Y]),
     true.




owl2dig_namespace_processing(L1, L):-
      dig_get_element(L1, E, _L2),
	E = element(_X, Y, L),
      retractall(namespace(_, _)), % remove all of the old namespace
      namespace_processing(Y),
      !.

owl2dig_namespace_processing(_, _):-!.


dig_file_out(OutFile, Text):-
	open(OutFile, write, Out, []),
      format(Out, '~w', [Text]),
	close(Out),
	true.




owl_dig([], ''):-
                !.

owl_dig([H|T], Text):-
                H = element(_,_,_),
                !,
		    owl_dig_element(H, Text1),
		    owl_dig(T, Text2),
                concat_atom([Text1, Text2], Text).

owl_dig([_H|T], Text):-
                !,
		    owl_dig(T, Text).


owl_dig_element(H, Text):-
	H = element('owl:Ontology', ['rdf:about' = ''], _),
	!,
      sformat(Text, '<!--Ontology about="NIL" -->'),
	true.

owl_dig_element(H, Text):-
	H = element('owl:Ontology', ['rdf:about' = C], _),
	!,
      sformat(Text, '<!-- Ontology about="~w" -->', [C]),
	true.

owl_dig_element(H, Text):-
	H = element('owl:Class', ['rdf:about' = 'http://www.w3.org/2002/07/owl#Thing'], []),
	!,
      sformat(Text, '<top/>', []),
	true.


owl_dig_element(H, Text):-
	H = element('owl:Class', ['rdf:about' = C], []),
	get_name(C,CN),
	cache_concept(CN),
	!,
      get_name(C, N),
      sformat(         Text, '<catom name="~w"/>', [N]),
	true.

owl_dig_element(H, Text):-
	H = element('owl:Class', ['rdf:ID' = C], []),
	cache_concept(C),
	!,
      get_name(C, N),
      sformat(Text, '<catom name="~w"/>', [N]).

owl_dig_element(H, Text):-
	H = element('owl:Class', ['rdf:resource' = C], []),
	get_name(C,CN),
	cache_concept(CN),
	!,
      get_name(C, N),
      sformat(Text, '<catom name="~w"/>', [N]).


owl_dig_element(H, Text):-
	H = element('owl:Class', ['rdf:about' = C], L),
	get_name(C,CN),
	cache_concept(CN),
	!,
      E = element('owl:Class', ['rdf:about' = C], []),
      owl_dig(E, L, Text),
	true.

owl_dig_element(H, Text):-
	H = element('owl:Class', ['rdf:ID' = C], L),
	cache_concept(C),
	!,
      get_name(C, C1),
      sformat(Text1, '<defconcept name="~w"/>', [C1]),
      declare_concept(C1),
	E = element('owl:Class', ['rdf:about' = C], []),
      owl_dig(E, L, Text2),
      concat_atom([Text1, Text2], Text).

owl_dig_element(H, Text):-
	H = element('owl:Class', ['rdf:resource' = C], L),
	!,
	E = element('owl:Class', ['rdf:about' = C], []),
      owl_dig(E, L, Text),
	true.

owl_dig_element(H, Text):-
	H = element('owl:Class', [], L),
      dig_get_element(L, E, L1),
      dig_get_element(L1, E1, _),
      E1 = nil,
      !,
      owl_dig_element(E, Text),
	true.


owl_dig_element(H, Text):-
	H = element('owl:Class', [], L),
      dig_get_element(L, E, L1),
      !,
      owl_dig(E, L1, Text),
	true.

owl_dig_element(H, Text):-
	H = element('owl:onProperty', ['rdf:resource' = R], _L),
	!,
      get_name(R, R1),
      sformat(Text, '<ratom name="~w"/>', [R1]),
      cache_role(R1),
	true.


owl_dig_element(E, Text):-
      E = element(Owl, ['rdf:parseType'='Collection'], L),
      owl_dig_voc(Owl, Dig, 2),
	!,
      sformat(Text1, '<~w>', [Dig]),
      owl_dig(L, Text2),
      sformat(Text3, '</~w>', [Dig]),
      concat_atom([Text1, Text2, Text3], Text).


owl_dig_element(E, Text):-
      E = element(Owl, ['rdf:resource'=C], []),
      owl_dig_voc(Owl, Dig, 2),
	!,
      get_name(C, N),
      sformat(Text1, '<~w><catom name="~w"/>', [Dig, N]),
      sformat(Text2, '</~w>', [Dig]),
	concat_atom([Text1, Text2], Text).


owl_dig_element(E, Text):-
      E = element(Owl, [], L),
      owl_dig_voc(Owl, Dig, 2),
	!,
      sformat(Text1, '<~w>', [Dig]),
      owl_dig(L, Text2),
      sformat(Text3, '</~w>', [Dig]),
	concat_atom([Text1, Text2, Text3], Text).

owl_dig_element(E, Text):-
      E = element(Owl, ['rdf:parseType'='Collection'], L),
      owl_dig_voc(Owl, Dig, 1),
	!,
      sformat(Text1, '<~w>', [Dig]),
      owl_dig(L, Text2),
      sformat(Text3, '</~w>', [Dig]),
      concat_atom([Text1, Text2, Text3], Text).


owl_dig_element(E, Text):-
      E = element(Owl, ['rdf:resource'=C], []),
      owl_dig_voc(Owl, Dig, 1),
	!,
      get_name(C, N),
      sformat(Text1, '<~w><catom name="~w"/>', [Dig, N]),
      sformat(Text2, '</~w>', [Dig]),
	concat_atom([Text1, Text2], Text).


owl_dig_element(E, Text):-
      E = element(Owl, [], L),
      owl_dig_voc(Owl, Dig, 1),
	!,
      sformat(Text1, '<~w>', [Dig]),
      owl_dig(L, Text2),
      sformat(Text3, '</~w>', [Dig]),
	concat_atom([Text1, Text2, Text3], Text).



owl_dig_element(H, Text):-
      H= element('owl:onProperty', [], L),
      !,
      owl_dig(L, Text).


owl_dig_element(H, Text):-
	H = element(Owl, ['rdf:about' = R], []),
      owl_dig_voc(Owl, Dig, 3),
	!,
      get_name(R, R1),
      sformat(Text, '<~w name="~w"/>', [Dig,  R1]),
	true.



owl_dig_element(H, Text):-
	H = element(Owl, ['rdf:ID' = R], []),
	owl_dig_voc(Owl, Dig, 3),
	!,
      get_name(R, R1),
      (	  Owl = 'owl:ObjectProperty'
      ->  cache_role(R1)
      ;	  true
      ),
      sformat(Text, '<~w name="~w"/>', [Dig, R1]),
	true.

owl_dig_element(H, Text):-
	H = element(Owl, ['rdf:ID' = R], L),
      owl_dig_voc(Owl, _Dig, 3),
	!,
      E=element(Owl, ['rdf:about'= R], []),
      owl_dig(E,L, Text),
	true.


owl_dig_element(H, Text):-
	H = element(Owl, ['rdf:about' = R], L),
      owl_dig_voc(Owl, _Dig, 3),
	!,
      E=element(Owl, ['rdf:about'= R], []),
      owl_dig(E, L, Text),
	true.




owl_dig_element(H, Text):-
	H = element('owl:SymmetricProperty', ['rdf:ID' = R], L),
	!,
      E = element('owl:ObjectProperty', ['rdf:about' = R], []),
      get_name(R, R1),
      sformat(Text1, '<equalr><ratom name="~w"/><inverse><ratom name="~w"/></inverse></equalr>',[R1, R1]),
      cache_role(R1),
      owl_dig(E, L, Text2),
	concat_atom([Text1, Text2], Text),
	true.


owl_dig_element(H, Text):-
	H = element('owl:TransitiveProperty', ['rdf:ID' = R], L),
	!,
      E = element('owl:ObjectProperty', ['rdf:about' = R], []),
      get_name(R, R1),
      sformat(Text1, '<transitive><ratom name="~w"/></transitive>',[R1]),
      cache_role(R1),
      owl_dig(E,L, Text2),
	concat_atom([Text1, Text2], Text).


owl_dig_element(H, Text):-
	H = element('owl:InverseFunctionalProperty', ['rdf:ID' = R], L),
	!,
      E = element('owl:ObjectProperty', ['rdf:about' = R], []),
      get_name(R, R1),
      sformat(Text1, '<equalr><ratom name="~w"/><inverse><ratom name="~w"/></inverse></equalr>',[R1, R1]),
      cache_role(R1),
      owl_dig(E, L, Text2),
	concat_atom([Text1, Text2], Text),
	true.



owl_dig_element(H, Text):-

	H = element('owl:Restriction', [], L),
	!,
      E = element('owl:onProperty', _, _),
      select(E, L, L1),
      (	  C = element('owl:valuesFrom', _, F),
	  memberchk(C, L)
      ->  select(C, L1, L2),
	  member(element('owl:Class',FA,_), F),
	  (   member('rdf:about'=On,FA)
	  ;   member('rdf:ID'=On,FA)
	  ), get_name(On,OnN),
	  owl_dig(E, L2, Text, OnN)
      ;	  owl_dig(E, L1, Text)
      ),
      true.

owl_dig_element(H, Text):-
	H = element('owl:Thing', ['rdf:about' = I], []),
      !,
      get_name(I, I1),
      sformat(Text, '<individual name="~w"/>', [I1]).



owl_dig_element(H, Text):-
	H = element('owl:Thing', ['rdf:about' = I], L),
      !,
      get_name(I, I1),
      sformat(Text1, '<instanceof><individual name="~w"/><top/></instanceof>', [I1]),
 %     sformat(Text1, '<defindividual name="~w"/>', [I1]),
      E= element('owl:Thing', ['rdf:about'=I], []),
      owl_dig(E, L, Text2),
	concat_atom([Text1, Text2], Text).

%% version 0.6.4
owl_dig_element(H, Text):-
	H = element('rdf:Description', ['rdf:about' = I], L),
      !,
      get_name(I, I1),
	E1 = element('owl:Thing', ['rdf:about' = I1], []),
      owl_dig(E1, L, Text).



owl_dig_element(H, Text):-
	(H = element('rdfs:Class', ['rdf:ID'=I], []);H = element('rdfs:Class', ['rdf:resource'=I], [])),
	!,
      get_name(I, I1),
      sformat(Text, '<catom name="~w"/>', [I1]),
	true.




owl_dig_element(H, Text):-
	(H = element(C, ['rdf:ID'=I], []);H = element(C, ['rdf:resource'=I], [])),
	!,
     get_name(I, I1),
     get_name(C, C1),
      sformat(Text, '<instanceof><individual name="~w"/><catom name="~w"/></instanceof>', [I1, C1]),
	true.





owl_dig_element(H, Text):-
	H = element(C, ['rdf:datatype'=_], [N]),
	!,
     get_name(C, C1),
      sformat(Text, '<attribute name="~w"/><sval>~w</sval>', [C1, N]).


owl_dig_element(H, Text):-
	H = element('rdfs:Class', ['rdf:ID'=I], L),
	!,
     get_name(I, I1),
 %     sformat(Text1, '<impliesc><catom name="~w"/><top/></impliesc>', [I1]),
     sformat(Text1, '<defconcept name="~w"/>', [I1]),
     declare_concept(I1),
     E = element('owl:Class', ['rdf:resource'=I],[]),
      owl_dig(E, L, Text2),
	concat_atom([Text1, Text2], Text),
	true.


owl_dig_element(H, Text):-
	H = element('rdf:Description', ['rdf:ID'=I], L),
	!,
     get_name(I, I1),
      sformat(Text1, '<defconcept name="~w"/>', [I1]),
      declare_concept(I1),
      E = element('owl:Class', ['rdf:resource'=I], []),
      owl_dig(E, L, Text2),
	concat_atom([Text1, Text2], Text),
	true.




owl_dig_element(H, Text):-
	H = element(C, ['rdf:ID'=I], L),
	!,
     get_name(I, I1),
     get_name(C, C1),
      sformat(Text1, '<instanceof><individual name="~w"/><catom name="~w"/></instanceof>', [I1, C1]),
      E = element(C, ['rdf:resource'=I], []),
      owl_dig(E, L, Text2),
	concat_atom([Text1, Text2], Text),
	true.


owl_dig_element(H, Text):-
	H = element('owl:AllDifferent', _A, L),
      dig_get_element(L, E, _L1),
      E = element('owl:distinctMembers', ['rdf:parseType'='Collection'], L2),
	!,
      owl_dig_processing(alldifferent, L2, Text),
	true.

owl_dig_element(H, ''):-
      H = element(_, _, _),
	!,
	format('***untranslated element: ~q~n', [H]),
      true.


owl_dig_element(_, ''):-!.


% Qualified Cardinality Constraints (with owl:valuesFrom)
owl_dig(E1, L, Text, On) :-
      dig_get_element(L, E, L1),
      E = element('owl:cardinality', _, [N]),
	!,
      sformat(Text1, '<and><atleast num="~w">', [N]),
      owl_dig_element(E1, Text2),
      sformat(Text3, '<catom name="~w"/></atleast>',[On]),
	sformat(Text4,'<atmost num="~w">', [N]),
      owl_dig_element(E1, Text5),
      sformat(Text6, '<catom name="~w"/></atmost></and>',[On]),
      owl_dig(E1, L1, Text7),
	concat_atom([Text1, Text2, Text3, Text4, Text5, Text6, Text7], Text).


owl_dig(E1, L, Text, On):-
      dig_get_element(L, E, L1),
      E = element('owl:minCardinality', _, [N]),
	!,
      sformat(Text1, '<atleast num="~w">', [N]),
      owl_dig_element(E1, Text2),
      sformat(Text3, '<catom name="~w"/></atleast>',[On]),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).

owl_dig(E1, L, Text, On):-
      dig_get_element(L, E, L1),
      E = element('owl:minCardinality', _, [N]),
	!,
      sformat(Text1, '<atleast num="~w">', [N]),
      owl_dig_element(E1, Text2),
      sformat(Text3, '<catom name="~w"/></atleast>',[On]),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).

owl_dig(E, L, T, _) :- owl_dig(E, L, T).


owl_dig(_C, [], ''):-!.

owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element(Owl, ['rdf:resource'=C2], []),
      owl_dig_voc(Owl, Dig, 1),
      E1 = element('owl:Class', ['rdf:about' = C],[]),
	!,
     get_name(C2, C3),
     get_name(C, C1),
      sformat(Text1, '<equalc><catom name="~w"/><~w><catom name="~w"/></~w></equalc>', [C1, Dig, C3, Dig]),
      owl_dig(E1, L1, Text2),
      concat_atom([Text1, Text2], Text).



owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element(Owl, ['rdf:resource'=C2], []),
      owl_dig_voc(Owl, Dig, 2),
	!,
      sformat(Text1, '<~w>', [Dig]),
      owl_dig_element(E1, Text2),
      get_name(C2, C1),
      sformat(Text3, '<catom name="~w"/></~w>',[C1, Dig]),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).

owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element(Owl, ['rdf:about'=C2], []),
      owl_dig_voc(Owl, Dig, 2),
	!,
      sformat(Text1, '<~w>', [Dig]),
      owl_dig_element(E1, Text2),
      get_name(C2, C1),
      sformat(Text3, '<catom name="~w"/></~w>',[C1, Dig]),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).

owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element(Owl, _X, L2),
      owl_dig_voc(Owl, Dig, 1),
      E1 = element('owl:Class', ['rdf:about' = C],[]),
	!,
      get_name(C, C1),
      sformat(Text1, '<equalc><catom name="~w"/><~w>', [C1, Dig]),
	owl_dig(L2, Text3),
      sformat(Text4, '</~w></equalc>',[Dig]),
      owl_dig(E1, L1, Text5),
	concat_atom([Text1, Text3, Text4, Text5], Text).


owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element(Owl, _X, L2),
      owl_dig_voc(Owl, Dig, 1),
	!,
      sformat(Text1, '<~w>', [Dig]),
	owl_dig(L2, Text3),
      sformat(Text4, '</~w>',[Dig]),
      owl_dig(E1, L1, Text5),
	concat_atom([Text1, Text3, Text4, Text5], Text).




owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element(Owl, _X, L2),
      owl_dig_voc(Owl, Dig, 2),
	!,
      sformat(Text1, '<~w>', [Dig]),
      owl_dig_element(E1, Text2),
	owl_dig(L2, Text3),
      sformat(Text4, '</~w>',[Dig]),
      owl_dig(E1, L1, Text5),
	concat_atom([Text1, Text2, Text3, Text4, Text5], Text).


owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('owl:cardinality', _, [N]),
	!,
      sformat(Text1, '<and><atleast num="~w">', [N]),
      owl_dig_element(E1, Text2),
      sformat(Text3, '<top/></atleast>'),
	sformat(Text4,'<atmost num="~w">', [N]),
      owl_dig_element(E1, Text5),
      sformat(Text6, '<top/></atmost></and>'),
      owl_dig(E1, L1, Text7),
	concat_atom([Text1, Text2, Text3, Text4, Text5, Text6, Text7], Text).

owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('owl:minCardinality', _, [N]),
	!,
      sformat(Text1, '<atleast num="~w">', [N]),
      owl_dig_element(E1, Text2),
      sformat(Text3, '<top/></atleast>'),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).


owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('owl:maxCardinality', _, [N]),
	!,
      sformat(Text1, '<atmost num="~w">', [N]),
      owl_dig_element(E1, Text2),
      sformat(Text3,'<top/></atmost>'),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).




owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('owl:hasValue',  ['rdf:resource'=V], []),
	!,
      owl_dig_element(E1, Text1),
      get_name(V, V1),
      sformat(Text2, '<iset><individual name="~w"/></iset>', [V1]),
      owl_dig(E1, L1, Text3),
	concat_atom([Text1, Text2, Text3], Text).

owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('owl:inverseOf',  ['rdf:resource'=V], []),
	!,
      get_name(V, V1),
      sformat(Text1, '<equalr><ratom name="~w"/><inverse>', [V1]),
      cache_role(V1),
      owl_dig_element(E, Text2),
      owl_dig(E1, L1, Text3),
	concat_atom([Text1, Text2, '</inverse></equalr>', Text3], Text).



owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('owl:hasValue', [], L3),
	!,
      owl_dig_element(E1, Text1),
      sformat(Text2, '<iset>'),
      owl_dig(L3, Text3),
      sformat(Text4, '</iset>'),
      owl_dig(E1, L1, Text5),
	concat_atom([Text1, Text2, Text3, Text4, Text5], Text).





owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdf:type', ['rdf:resource' = 'http://www.w3.org/2002/07/owl#FunctionalProperty'],[]),
	!,
      sformat(Text1, '<functional>'),
      owl_dig_element(E1, Text2),
      sformat(Text3, '</functional>'),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).


owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdf:type', ['rdf:resource' = 'http://www.w3.org/2002/07/owl#ObjectProperty'],[]),
	!,
      sformat(Text1, '<functional>'),
      owl_dig_element(E1, Text2),
      sformat(Text3, '</functional>'),
      owl_dig(element(E1), L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).


owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdf:type', ['rdf:resource' = 'http://www.w3.org/2002/07/owl#DatatypeProperty'],[]),
	!,
      sformat(Text1,'<rangeint>'),
      owl_dig_element(E1, Text2),
      sformat(Text3,'</rangeint>'),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).


owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdf:type', ['rdf:resource' = 'http://www.w3.org/2002/07/owl#TransitiveProperty'],[]),
	!,
      sformat(Text1, '<transitive>'),
      owl_dig_element(E1, Text2),
      sformat(Text3, '</transitive>'),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).

owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdf:type', ['rdf:resource' = 'http://www.w3.org/2002/07/owl#SymmetricProperty'],[]),
	!,
      sformat(Text1, '<inverse>'),
      owl_dig_element(E1, Text2),
      sformat(Text3, '</inverse>'),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).


owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdf:type', ['rdf:resource' = 'http://www.w3.org/2002/07/owl#Thing'],[]),
      E1 = element('owl:Thing', ['rdf:about' = I], []),
	!,
      get_name(I, N),
      sformat(Text1, '<defindividual name="~w"/>', [N]),
      owl_dig(E1, L1, Text2),
	concat_atom([Text1, Text2], Text).


owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdf:type', ['rdf:resource' = R2],[]),
      (E1 = element('owl:DatatypeProperty', ['rdf:about' = R1], []);E1 = element('owl:ObjectProperty', ['rdf:about' = R1], [])),
	!,
      get_name(R1, N1),
      get_name(R2, N2),
      sformat(Text1, '<impliesr><ratom name="~w"/><ratom name="~w"/></impliesr>', [N1,N2]),
      cache_role(N1),
      cache_role(N2),
      owl_dig(E1, L1, Text2),
	concat_atom([Text1, Text2], Text).

owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('owl:inverseOf', [], L2),
      E1 = element('owl:ObjectProperty', ['rdf:about' = R1], []),
	!,
      get_name(R1, N1),
      sformat(Text1, '<equalr><ratom name="~w"/>', [N1]),
      cache_role(N1),
      dig_get_element(L2, E2,_),
      owl_dig_element(E2, Text3),
      owl_dig(E1, L1, Text2),
	concat_atom([Text1, Text3, '</equalr>', Text2], Text).




owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element(A, ['rdf:datatype' = 'http://www.w3.org/2001/XMLSchema#integer'],[V]),
      E1 = element('owl:Thing', ['rdf:about' = I], []),
	!,
      get_name(I, N1),
      get_name(A, N2),
      sformat(Text1, '<value><individual name="~w"/><attribute name="~w"/><sval>~w</sval></value>', [N1, N2, V]),
      owl_dig(E1, L1, Text2),
	concat_atom([Text1, Text2], Text).

owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E =  element('owl:hasValue', ['rdf:datatype'='http://www.w3.org/2001/XMLSchema#string'], [I]),
      E1 = element('owl:onProperty', [], LE1),
      dig_get_element(LE1, E2, _),
      (E2 = element('owl:DatatypeProperty', ['rdf:ID'=A], []);E2 =  element('owl:DatatypeProperty', ['rdf:about'=A], [])),
	!,
      get_name(I, N1),
      get_name(A, N2),
      sformat(Text1, '<value><attribute name="~w"/><sval>~w</sval></value>', [N1, N2]),
      owl_dig(E1, L1, Text2),
	concat_atom([Text1, Text2], Text).





owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E =  element(Owl, ['rdf:resource'=C], []),
      owl_dig_voc(Owl, Dig, 4),
	!,
      sformat(Text1, '<~w>', [Dig]),
      owl_dig_element(E1, Text2),
      get_name(C, C1),
      sformat(Text3, '<catom name="~w"/></~w>',[C1, Dig]),
      owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).




owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E =  element(Owl, [], L2),
      owl_dig_voc(Owl, Dig, 4),
	!,
      sformat(Text1, '<~w>',[Dig]),
      owl_dig_element(E1, Text2),
      owl_dig(L2, Text3),
      sformat(Text4, '</~w>', [Dig]),
      owl_dig(E1, L1, Text5),
	concat_atom([Text1, Text2, Text3, Text4, Text5], Text).




owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdfs:subPropertyOf', [], L2),
 	!,
      sformat(Text1, '<impliesr>'),
      owl_dig_element(E1, Text2),
      owl_dig(L2, Text3),
      sformat(Text4, '</impliesr>'),
      owl_dig(E1, L1, Text5),
	concat_atom([Text1, Text2, Text3, Text4, Text5], Text).


owl_dig(E1, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdfs:subPropertyOf', ['rdf:resource' = R], []),
 	!,
      sformat(Text1, '<impliesr>'),
      owl_dig_element(E1, Text2),
      get_name(R, R1),
      sformat(Text3, '<ratom name="~w"/></impliesr>', [R1]),
      cache_role(R1),
	owl_dig(E1, L1, Text4),
	concat_atom([Text1, Text2, Text3, Text4], Text).


% ignoring the label
owl_dig(C, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdfs:label', _, [_Label]),
	!,
	owl_dig(C, L1, Text),
      true.



owl_dig(C, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdfs:comment', _, [Comment]),
	!,
      sformat(Text1, '<!-- ~w -->', [Comment]),
      owl_dig(C, L1, Text2),
      concat_atom([Text1, Text2], Text),
	true.

owl_dig(C, L, Text):-
      dig_get_element(L, E, L1),
      E = element('rdf:type', [], L2),
	!,
      owl_dig_element(C, Text1),
      owl_dig(L2, Text2),
      owl_dig(C, L1, Text3),
      concat_atom(['<instanceof>', Text1, Text2, '</instanceof>', Text3], Text),
	true.


owl_dig(C, L, Text):-
      (C = element('owl:Class', ['rdf:resource' = I], []);C = element('rdf:Description', ['rdf:resource' = I], [])),
      dig_get_element(L, E, L1),
      E = element('rdf:type', ['rdf:resource'= I2], []),
	!,
     get_name(I, N1),
     get_name(I2,N2),
     sformat(Text1, '<impliesc><catom name="~w"/><catom name="~w"/></impliesc>', [N1,N2]),
      owl_dig(C, L1, Text2),
      concat_atom([Text1, Text2], Text),
	true.

owl_dig(C, L, Text):-
      C = element('rdf:Description', ['rdf:resource' = I], []),
      dig_get_element(L, E, L1),
      E = element(R, ['rdf:resource'= I2], []),
	!,
     get_name(I, N1),
     get_name(I2,N2),
     get_name(R, N3),
	sformat(Text1, '<related><individual name="~w"/><ratom name="~w"/><individual name="~w"/></related>', [N1, N3, N2]),
      cache_role(N3),
      owl_dig(C, L1, Text2),
      concat_atom([Text1, Text2], Text),
	true.


owl_dig(C, L, Text):-
      C = element(_C1, ['rdf:resource' = I], []),
      dig_get_element(L, E, L1),
      E = element(_C2, ['rdf:datatype'= _], _),
	!,
      get_name(I, I1),
	sformat(Text1, '<value><individual name="~w"/>', [I1]),
      owl_dig_element(E, Text2),
      sformat(Text3, '</value>', []),
      owl_dig(C, L1, Text4),
      concat_atom([Text1, Text2, Text3, Text4], Text),
	true.


owl_dig(_C, L, Text):-
     dig_get_element(L, E, _L1),
     E = nil,
     !,
     Text = ''.



owl_dig(C, L, Text):-
	!,
	format(user_error, '***untranslated list: ~q:~q~n', [C, L]),
      Text = '',
      true.


owl_dig_voc('owl:intersectionOf', and, 1):-!.
owl_dig_voc('owl:complementOf', not, 1):-!.
owl_dig_voc('owl:unionOf', or, 1):-!.
owl_dig_voc('owl:oneOf', iset, 1):-!.


owl_dig_voc('rdfs:subClassOf', impliesc, 2):-!.
owl_dig_voc('owl:disjointWith', disjoint, 2):-!.
owl_dig_voc('owl:equivalentClass', equalc, 2):-!.
owl_dig_voc('owl:allValuesFrom', all, 2):-!.
owl_dig_voc('owl:someValuesFrom', some, 2):-!.

owl_dig_voc('owl:ObjectProperty', ratom, 3):-!.
owl_dig_voc('owl:FunctionalProperty', ratom, 3):-!.
owl_dig_voc('owl:DatatypeProperty', attribute, 3):-!.
owl_dig_voc('rdfs:range', range, 4):-!.
owl_dig_voc('rdfs:domain', domain, 4):-!.


owl_dig_processing(alldifferent, [], Text):-
       !,
       Text=''.

owl_dig_processing(alldifferent, L, Text):-
       dig_get_element(L, E, L1),
       E = element(C,['rdf:about'=I],[]),
       !,
       get_name(I, I1),
     	get_name(C, C1),
       sformat(Text1, '<defindividual name="~w"/>', [I1]),
       sformat(Text2, '<instanceof><individual name="~w"/><catom name="~w"/></instanceof>', [I1, C1]),
       owl_dig_processing(alldifferent, L1, Text3),
	 concat_atom([Text1, Text2, Text3], Text),
	 true.

owl_dig_processing(alldifferent, _, Text):-
       Text=''.



namespace_processing([]):-!.
namespace_processing([N = S|T]):-
      assert(namespace(N, S)),
      !,
	namespace_processing(T).

namespace_processing([_|T]):-
      namespace_processing(T).


get_namespace(xmlns, M):-
     namespace(xmlns, M),
     nonvar(M),
     !.

get_namespace(N, M):-
     sub_string(N, X, _Y, _Z, ':'),
     X > 0,
     namespace(N, M),
     nonvar(M),
     !.


get_namespace(S, N):-
     concat_atom(['xmlns:', S], NS),
     namespace(NS, N),
     nonvar(N),
     !.

get_namespace(_, ''):-!.

/* type0: only IDs
get_name(N,N1) :-
	atom_concat('#',N1,N).
get_name(N,N).
*/

% type1: #Name
get_name(N, N1):-
         sub_string(N, X, _Y, Z, '#'),
	   X = 0,
         !,
         sub_string(N, 1, Z, _Z1, N2),
         get_namespace('xml:base', NS),
         concat_atom([NS, N2], N1).

% type2: BASE#Name
get_name(N, N1):-
         sub_string(N, X, _Y, _Z, '#'),
	   X > 0,
         !,
         N1= N.


% type3: NS:Name
get_name(N, N1):-
         sub_string(N, X, _Y, Z, ':'),
	   X > 0,
         !,
         sub_string(N, 0, X, _Z1, NS),
         X1 is X + 1,
         sub_string(N, X1, Z, _Z2, M),
         get_namespace(NS, Text1),
         concat_atom([Text1, M], N1).

% type4: Name
get_name(N, N1):-
         !,
         get_namespace('xml:base', NS),
         concat_atom([NS, N], N1).

% guard against undeclared concepts and roles

:- dynamic concept/2, role/2, declared_concept/2, declared_role/2.

undeclared_concepts(Ss) :-
	thread_self(T), !,
	findall(C, ( concept(T,C), \+declared_concept(T,C) ), Cs),
	sort(Cs,Ss).

undeclared_roles(Ss) :-
	thread_self(T), !,
	findall(C, ( role(T,C), \+declared_role(T,C) ), Cs),
	sort(Cs,Ss).

format_concept(C,T) :- sformat(T,'<defconcept name="~w"/>~n',[C]).

format_role(C,T) :- sformat(T,'<defrole name="~w"/>~n',[C]).

format_concepts(Cs, Text) :-
	maplist(format_concept, Cs, Ts),
	atomic_list_concat(Ts, Text).

format_roles(Cs, Text) :-
	maplist(format_role, Cs, Ts),
	atomic_list_concat(Ts, Text).

cache_concept(C) :-
	thread_self(T), !,
	assertz(concept(T,C)).
cache_role(C) :-
	thread_self(T), !,
	assertz(role(T,C)).
declare_concept(C) :-
	thread_self(T), !,
	assertz(declared_concept(T,C)).

retract_declaration_cache :-
	thread_self(T), !,
	retractall(concept(T,_)),
	retractall(role(T,_)),
	retractall(declared_concept(T,_)),
	retractall(declared_role(T,_)).



