
/*
Create the table(s) showing derivation
of subset tree of value spaces of
numeric XSD classes.

*/

:- dynamic backgroundToggle/1 .

backgroundToggle(on).

% infinite datatypes
idt(decimal).
idt(X) :- idt(X,_).

% infinite derived types
idt(integer,decimal).
idt(nonPositiveInteger,integer).
idt(negativeInteger,nonPositiveInteger).
idt(nonNegativeInteger,integer).
idt(positiveInteger,nonNegativeInteger).


% finite types
fdt(double).
fdt(float).
fdt(X) :- fdt(X,_).
fdt({1}).
fdt({-1}).
fdt({0}).

% finite derived types
fdt(long,integer).
fdt(int,long).
fdt(short,int).
fdt(byte,short).
fdt(unsignedLong,nonNegativeInteger).
fdt(unsignedInt,unsignedLong).
fdt(unsignedShort,unsignedInt).
fdt(unsignedByte,unsignedShort).

dt(D) :- idt(D).
dt(D) :- fdt(D).

dts(L) :-bagof(X,dt(X),L).

background(X) :-
   retract(backgroundToggle(Y)),
   toggle(X,Y),
   !,
   assert(backgroundToggle(X)).
toggle(on,off).
toggle(off,on).
toggle(_,_).
background(0,off) :-
  background(off).
background(1,on) :-
  background(on).
setBackground(N) :-
   N1 is N mod 2,
   background(N1,_).


anchor('[K]',cardinality).
anchor('[D]',derived).
anchor('[1]',one).
anchor('[-1]',minusOne).
anchor('[U]',unsigned).
anchor('[F]',float).
anchor('[T]',transitivity).
anchor('[X]',intDouble).
anchor('[Y]',shortFloat).
anchor('[Z]',overFlow).
anchor('[P]',proper).
anchor('[V]',unsigned2).
anchor('[0]',zero).
anchor('[I]',infinity).

comp(Infinite,Finite,'[K]',notSubset) :-
   idt(Infinite),
   fdt(Finite).
comp(Derived,Base,'[D]',subset) :-
   fdt(Derived,Base).
comp(Derived,Base,'[D]',subset) :-
   idt(Derived,Base).
comp(D,D,=,subset).
comp({0},byte,'[0]',subset).
comp({0},unsignedByte,'[0]',subset).
comp({0},positiveInteger,'[0]',notSubset).
comp({0},nonPositiveInteger,'[0]',subset).
comp({0},negativeInteger,'[0]',notSubset).
comp({1},byte,'[1]',subset).
comp({1},unsignedByte,'[1]',subset).
comp({1},positiveInteger,'[1]',subset).
comp({1},nonPositiveInteger,'[1]',notSubset).
comp({-1},byte,'[-1]',subset).
comp({-1},negativeInteger,'[-1]',subset).
comp({-1},nonNegativeInteger,'[-1]',notSubset).
comp(unsignedByte,short,'[U]',subset).
comp(unsignedShort,int,'[U]',subset).
comp(unsignedInt,long,'[U]',notSubset).
comp(unsignedByte,byte,'[V]',notSubset).
comp(unsignedShort,short,'[V]',notSubset).
comp(unsignedInt,int,'[V]',notSubset).
comp(unsignedLong,long,'[V]',notSubset).
comp(float,double,'[F]',subset).
comp(int,double,'[X]',subset).
comp(unsignedInt,double,'[X]',subset).
comp(short,float,'[Y]',subset).
comp(unsignedShort,float,'[Y]',subset).
comp(long,double,'[Z]',notSubset).
comp(unsignedLong,double,'[Z]',notSubset).
comp(int,float,'[Z]',notSubset).
comp(unsignedInt,float,'[Z]',notSubset).
comp(float,decimal,'[I]',notSubset).


comp(A,B,'[P]',notSubset) :-
   comp(B,A,_,subset), A \= B.

comp(_,_,'?',nocompare).

:- dynamic tc_comp/4.
compute_tc :-
  abolish(tc_comp,4),
  fail.
compute_tc :-
  dt(A),dt(B),
  comp(A,B,L,Comp),
  \+ L = '?',
  assert(tc_comp(A,B,L,Comp)),
  fail.
compute_tc :-
  repeat,
  (add_tc->fail;true),
  !.
add_tc :-
  tc_comp(A,B,_,subset),
  tc_comp(B,C,_,subset),
  ( tc_comp(A,C,_,N)->N=notSubset,wuser([error1(A,C)]),fail;true ),
  assertz(tc_comp(A,C,'[T]',subset)).
add_tc :-
  tc_comp(A,C,_,subset),
  tc_comp(B,C,_,notSubset),
  ( tc_comp(B,A,_,N)->N=subset,wuser([error2(B,A,C)]),fail;true ),
  assertz(tc_comp(B,A,'[T]',notSubset)).
add_tc :-
  tc_comp(B,A,_,subset),
  tc_comp(B,C,_,notSubset),
  ( tc_comp(A,C,_,N)->N=subset,wuser([error3(B,A,C)]),fail;true ),
  assertz(tc_comp(A,C,'[T]',notSubset)).

comp2(A,B,C,D) :-
  tc_comp(A,B,C,D).
comp2(_,_,'?',nocompare).

table1 :-
  tablehdr,
  dt(D),
  row(D),
  fail.
table1 :-
  write('</table>').


table2 :-
  compute_tc,
  tablehdr,
  dt(D),
  row2(D),
  fail.
table2 :-
  write('</table>').

tablehdr :-
   dts(AllDatatypes),
   write('<table border="1">'),
   member(N,[0,1,2,3,4]),
   length(L,N),
   append(L,Datatypes,AllDatatypes),
   setBackground(N),
   (N=0 ->
      write('<tr><th>Types</th>') ;
      wlist(['<tr><th></th><th colspan="',N,'"></th>']) ),
   tableHdrRow(Datatypes),
   wlist(['</tr>',nl]),
   fail.
tablehdr.

tableHdrRow([H,A,B,C,D,E|Rest]) :-
   background(Bckgrd),
   wlist(['<th colspan="5" align="left" class="tblHdr-',Bckgrd,'">',H,'</th>',nl]),
   !,
   tableHdrRow([E|Rest]).
tableHdrRow([H|R]) :-
   background(Bckgrd),
   length([H|R],N),
   wlist(['<th colspan="',N,'" align="left" class="tblHdr-',Bckgrd,'">',H,'</th>']).


cell(Class,Text) :-
   anchor(Text,Anchor),
   !,
   background(Bckgrd),
   wlist(['<td class="',Class,-,Bckgrd,'"><a href="#',Anchor,'"><span class="',Class,-,Bckgrd,'">',Text,'</span></a></td>']).
cell(Class,Text) :-
   background(Bckgrd),
   wlist(['<td class="',Class,-,Bckgrd,'">',Text,'</td>']).
row(D1) :-
  wlist(['<tr><th align="right">',D1,'</th>']),
  setBackground(0),
  dt(D2),
  once(comp(D1,D2,Text,Class)),
  cell(Class,Text),
  fail.
row(D1) :-
  write('</tr>'),nl.
row2(D1) :-
  wlist(['<tr><th align="right">',D1,'</th>']),
  setBackground(0),
  dt(D2),
  once(comp2(D1,D2,Text,Class)),
  cell(Class,Text),
  fail.
row2(D1) :-
  write('</tr>'),nl.

wlist([nl|T]) :- !, nl, wlist(T).
wlist([X|T]) :- write(X), wlist(T).
wlist([]).
wuser(L) :-
   telling(T),
   tell(user),
   wlist(L),
   tell(T).
   
   
   
   

