
% needs to add back in ns handling.
% and see if this is a good XML encoding.  :-)

:- ensure_loaded(library('semweb/rdf_db')).
:- ensure_loaded(library(sgml)).

description(Id,
	    element(Tag, Attrs, Children),
	    [ % rdf(Id, rdf_type, x_Element),
	      rdf(Id, x_tag, literal(Tag)),   % consider URI if xmlns
	      rdf(Id, x_attributes, Attrs),
	      rdf(Id, x_children, Children)
	    ]
	   ).

description(Id,
	    A=B,
	    [ rdf(Id, x_attribute, A),
	      rdf(Id, x_value, B)
	    ]
	   ).

description(literal(X), literal(X), []).

description(Id,
	    [First | Rest],
	    [ rdf(Id, rdf_first, First),
	      rdf(Id, rdf_rest, Rest)
	    ]
	   ).

description(rdf_nil,
	    [],
	    []
	   ).

description(Id,
	    rdf(S,P,O),
	    [ rdf(Id, rdf_subject, S),
	      rdf(Id, rdf_predicate, P),
	      rdf(Id, rdf_object, O)
	    ]
	   ).
	    
% Add rdf triples as necessary, and bind Id as necessary, so that Id
% matches the given structure....    I think we need
% SourceOK & SourceToUse.  :-(
ensure_described(Structure, Id, Source) :-
	ground(Structure),
	(   match_description(Structure, Id, Source)
	;   describe(Structure, Id, Source)
	).
	
describe(X,X,_) :- atom(X).
%describe(A:B,X,_) :- atom(A), atom(B), rdf_global_id(A:B, X).
describe(Structure, Id, Source) :-
	description(Id, Structure, Triples),
	% rdf_global_id(IdX, Id),
	(   var(Id)
	->  gensym(foo, Id)
	;   true
	),
	forall(member(rdf(S,P,O), Triples),
	       (   ensure_described(S, SI, Source),
		   ensure_described(P, PI, Source),
		   ensure_described(O, OI, Source),
		   rdf_assert(SI,PI,OI,Source)
	       )
	      ).


match_description(Structure, Id, Source) :-
	(   ground(Structure)
	;   ground(Id)
	),
	%(   ground(IdQ)
	%->  rdf_global_id(IdQ, Id)
	%;   Id = IdQ
	%),
	description(Id, Structure, Triples),
	%rdf_global_id(IdX, Id),
	forall(member(rdf(S,P,O), Triples),
	       (   match_description(S, SI, Source),
		   match_description(P, PI, Source),
		   match_description(O, OI, Source),
		   rdf(SI,PI,OI,Source)
	       )).

% aka "expand"
% ....  replace an atom about which something is known in
%       the rdf store with a term containing the same information
%       [ some, or all? ]
%
% how do you know if it's complete?   ALL triples using the
% term must be-regenerated from this term -- or all used, at least.
% ... but that's sort of implied here.    SORT OF...
%
%    "termify"    triples_to_prolog(Id, Term, Sources)
%                 triples_to_prolog(Id, Term, [source_checker(SC),
%                                              sources_used(SourceList)])
%  (or maybe a backtrackable adder for Sources)
%

recognize(Structure, Id, Source) :-
	description(Id, Structure, Triples),
	match_all(Source, Triples).
match_all(_Source, []).
match_all(Source, [rdf(S,P,O) | Triples]) :-
	rdf(S,P,O, Source),
	match_all(Source, Triples).


recognize_deep(Structure, Id, Source) :-
	description(Id, Structure, Triples),
	match_all_deep(Source, Triples).
match_all_deep(_Source, []).
match_all_deep(Source, [rdf(S,P,O) | Triples]) :-
	rdf(S,P,OId, Source),
	(   recognize_deep(O, OId, Source)
	->  true
	;   O = OId    % don't force recognition -- return Id instead
	),
	match_all_deep(Source, Triples).




ex1(element(p,
	    [],
	    ['A', 'Silly', 'Demo']
	    )
   ).

ex2(element(p,
	    [a=b],
	    ['A', 'Silly', 'Demo']
	    )
   ).

/*

  ex1(X), describe(X, Id, me).

 recognize_deep(Structure, foo1, _).


  possible bug -- too much re-use?


sgml_package_example(X), describe(X, Id, me).



  
  */

qtest :-
	sgml_package_example(XML),
	describe(XML, ID, me),
	recognize_deep(XML2, ID, me),
	XML = XML2.

sgml_package_example(
         [ element(html,
             [],
             [ element(head,
           [],
           [ element(title,
               [],
               [ 'Demo'
               ])
           ]),
         element(body,
           [],
           [ '\n',
             element(h1,
               [ align = center
               ],
               [ 'This is a demo'
               ]),
             '\n\n',
             element(p,
               [],
               [ 'Paragraphs in HTML need not be closed.\n'
               ]),
             element(p,
               [],
               [ 'This is called `omitted-tag\' handling.'
               ])
           ])
             ])
         ]
        ).

