Failing to use //div as xpath selector

?- prolog_flag(version,X).
X = ‘SWI-Prolog 8.0.3 (x86_64-linux): Jun 19 2019, 14:01:15’.

My code looks like this:

:- use_module(library(http/http_client)).
:- use_module(library(http/http_open)).
:- use_module(library(xpath)).

?- j2(P, //div, X),length(X,XL), show(X).
ERROR: Syntax error: Unbalanced operator
ERROR: j2(P, //di
ERROR: ** here **
ERROR: v, X),length(X,XL), show(X) . 

If I wrap it in singles as an atom, it just fails:

?- j2(P, '//div', X),length(X,XL), show(X).
false.

I am sure I had this problem a very long time ago but I couldn’t find it on the forums… how on earth do I get to be able to specify a DIV tag!

I was having such fun until this came along!! I am sure it’s simple once you know what you are doing…

Thanks,
Sean.

I believe that the ‘//’ is an operator, which is why '//div' fails. Does '//'(div) work?

EDIT: not sure why it’s not working as //div though; xpath should be exporting that op

div/2 is also an operator!

Let me try… yes, it does.

So…attempting to understand…using //div just like that is functor(args), is ‘//’(div) is writing it in functional form so that it doesn’t get parsed the “wrong” way because of operator precedence?

And, thanks James!

Oh right, div is also an arithmetic operator, of course!

I believe so; //'div' should work properly as well and is probably a better solution (because the problem isn’t about // as an operator, it’s that div is being treated as an operator, not an atom).

Yes, //‘div’ also works… but not sure why…so…hacky…I see that…

?- ‘//’(div) = //‘div’.
true.

so they are the same thing, the functor ‘//’ with the atom div as the sole argument.

Just a case of operator clash as @jamesnvc pointed out:

?- current_op(P, T, //).
P = 400,
T = fx ;
P = 400,
T = yfx.

?- current_op(P, T, div).
P = 400,
T = yfx.

As usual, you can solve the clash using parenthesis:

?- write(//(div)).
// (div)
true.
1 Like

Ah! Thanks Paulo.

If you use modules and have no use for div for arithmetic in that module you can also do this to locally kill the operator:

:- op(0, yfx, div).

Not sure this should be considered good or bad style. It certainly suffers from portability as some Prolog systems (still) have only global operators.

the op//3 and generally definiting operators is not something I have ever done so it’s all a bit mysterious to me…it’s something I keep meaning to study but somehow I have managed thus far without needed a custom operator.

Do you know of any good tutorials, I have found some but they tend to be terse and not very helpful…if I can understand I#d write my own…currently working in a custom little web server with Prolog (I didn’t get on with