:- module(scasp_swish, []). :- use_module(library(http/html_write)). :- use_module(library(pengines)). :- use_module(library(apply)). :- use_module(library(lists)). :- use_module(swish(lib/config)). :- use_module(library(scasp/embed)). :- use_module(library(scasp/html)). :- use_module(library(scasp/output)). /** s(CASP) adapter for SWISH Hook into SWISH to make the model and justification available in the SWISH web interface. */ :- multifile swish_config:config/2, swish_trace:post_context/1, swish_trace:post_context/3. %! swish_trace:post_context(+Dict) is semidet. % % Called before the other context extraction. We use it to name the % variables. Note that we also do the work for % swish_trace:post_context/3 here because we need to remove the % attributes. % % The model and justification are communicated as a Prolog string % holding HTML. That is dubious as the SWISH infrastructure turns this % into escaped HTML which we need to undo in SWISH' `runner.js`. swish_trace:post_context(Dict) :- _{bindings:Bindings0} :< Dict, swish_config:config(scasp_model_var, ModelVar), swish_config:config(scasp_justification_var, JustificationVar), selectchk(ModelVar = HTMLModel, Bindings0, Bindings1), selectchk(JustificationVar = HTMLJustification, Bindings1, Bindings), pengine_self(Module), scasp_model(Module:Model), scasp_justification(Module:Justification, []), Term = t(Bindings, Model, Justification), findall(HTMLModel-HTMLJustification, % revert backtrackable changes to_html(Module:Term, HTMLModel, HTMLJustification), [ HTMLModel-HTMLJustification ]). :- det(to_html/3). to_html(M:Term, HTMLModel, HTMLJustification) :- Term = t(Bindings, Model, Justification), maplist(set_name, Bindings), ovar_analyze_term(Term), inline_constraints(Term, []), html_string(html_model(M:Model, []), HTMLModel), html_string(html_justification_tree(M:Justification, []), HTMLJustification). set_name(Name = Var) :- ( var(Var) -> ovar_set_name(Var, Name) ; true ). swish_config:config(scasp_model_var, '_swish__scasp_model'). swish_config:config(scasp_justification_var, '_swish__scasp_justification'). %! swish_trace:post_context(+Name, +Goal, -Var) is semidet. % % Bind Var with the context information that belongs to Name. Note % that we suppress normal residuals using the first clause as we % report these through the others. The model and justification are % already emitted in swish_trace:post_context/1 above. swish_trace:post_context(Name, _Goal, _) :- swish_config(residuals_var, Name), scasp_model(_), !. :- meta_predicate html_string(//, -). html_string(Goal, HTML) :- phrase(Goal, Tokens), with_output_to(string(HTML0), print_html(Tokens)), split_string(HTML0, "", "\n ", [HTML]).