Type Error when pengines tries to return attributed variables

Once again, I am coming to you asking for help getting attributed variables out of Prolog and into Python </bernie sanders meme>

I’m running a pengines server that has some s(CASP) code in it that returns attributed variables (numerical and disequality constraints). When I run it in the top level, there are no issues. When I access the same code through pengines, I get a 500 error from the pengines server. If I turn on debugging for the server I see this error message:

% [Thread 9] [1] 500 ERROR: numbervars/4: Type error: `[swish_default_template{A:bobult,Attributes:[_918 ∉ 
[jason],put_attr(_918,scasp_output,name(A))],Model:[not(-can_wfh(_794{_794 ∉ [jason], 
scasp_output = ...})),can_wfh(bobult),-can_wfh(jason)],Tree:query-[can_wfh(bobult)-
[],o_nmr_check-[not(o_chk_1)-[not(-can_wfh(_794{_794 ∉ [jason], scasp_output = ...}))-[],-
can_wfh(jason)-[],not(can_wfh(jason))-[]]]]}]' contains attributed variables

% [Thread 9] Wiping posted data

My understanding of what numbervars is doing is taking things like _794 and replacing them with things like A. If there’s a short-term workaround that would see me lose that benefit, that would not be the end of the world. But ultimately, I just want to get out of pengines everything I could get out of the top level.

If you would need a package that you could download to replicate the issue, let me know, but any minimal pengines server that exposes a predicate that returns an attributed variable would probably recreate the problem, I think. The s(CASP) code that is generating the issue for me is something like this:

:- use_module(library(scasp)).

person(bobult).
person(jane).
person(jason).
can_wfh(bobult).
-can_wfh(jason).

The query calls scasp(can_wfh(A),…)

Whatever you can suggest that would get me moving again would be very appreciated, because at the moment I’m stuck.

Thanks!

I afraid that the Pengines API was not designed with attributed variables in mind. That can probably be fixed, although the “how” is not so clear.

The alternative is to get rid of them. The generic way to do so is by calling copy_term/3 on the output. That results in a term without constraints and a list of goals that represents the pending constraints.

But, I think I suggested this before, why not consider the stand-alone server that comes with the sCASP sources in examples/dyncall/http.pl. That provides a much simpler interface than Pengines and is way easier to manage.

If the above doesn’t help, I’ll indeed need something to replicate. Yes, attributed variables will replicate the error for Pengines, but the question is how to represent them in a sensible way. They do not fit in the Pengines default answer, so we’d have to extend the protocol. That is not on the top of my priority list.

I’m not sure I understand what is gained by moving from pengines, which doesn’t do it, to sCASP, which also doesn’t do it. It is the second time you’ve suggested it, but I still don’t understand the motivation. You mention that pengines is more complicated, but I don’t think it’s the complication causing this problem, is it?

In the meantime I’ll play around with copy_term, which it sounds like I would need to do with scasp’s server anyway.

Thanks for the quick reply.

The sCASP server can deal with constraints. Just run

 swipl examples/dyncall/http.pl

Open http://localhost:8080/, past your query and see the result as HTML or JSON. The JSON format is a proposal. I think it would be great to have an agreed JSON format for sCASP. JSON is very easy to process in just about any language. See the help link for accessing the server using an HTTP POST request rather than the browser.

But yes, I think you can get what you want from Pengines using copy_term/3.

1 Like

I spent some time fighting with copy_term to no avail. It seems like it works unless the attributes attach to variables in the user’s query.

This is as close as I’ve gotten, let me know if there’s something obviously wrong.

:- meta_predicate blawxrun(0,-,-,-).

blawxrun(Query,Tree,Model,Attributes) :-
    scasp(Query, [tree(TempTree), model(TempModel), source(false)]),
    ovar_analyze_term(t(Query, TempTree, TempModel), [name_constraints(true), name_prefix('Var_')]),
    (   term_attvars(t(Query, TempTree, TempModel), [])
    ->  Attributes = [], Tree=TempTree,Model=TempModel
    ;   copy_term(t(Query, TempTree, TempModel), NewCopy, Attributes),
    t(Query, Tree, Model) = NewCopy
    ).

I decided to try the sCASP http server, as per your suggestion, and it runs, but localhost:8080/ and localhost:8080/scasp return 404 errors. I note that dev.swi-prolog.org/scasp/ has the same problem.

Remember when I was reluctant about switching horses mid-stream? This is why. :wink:

But I’m on two horses, now, so if anyone has any advice that would make either of them get out of this damned stream, I’d appreciate it.

I was able to walk through the output of the predicate in the top level to see that copy_term was not removing the attributes from the query variables, so I added

...
term_variables(Query,QueryVars),
maplist(delattr,QueryVars).

and it seems to be working, now!

Have you tried copy_term_nat/2 ?