3

Sometimes I see terms like: X = a:b or X = a-b

I can do requests like X = Y:Z and the compiler unifies Y with a and Z with b, as expected.

Now my answer: Which characters (or sequence of characters) am I allowed to use to combine two Prolog atoms?!

Maybe you can give me some links with further informations about this issue.

Thanks for your help and kind regards from Germany

false
  • 10,264
  • 13
  • 101
  • 209
mrbela
  • 4,477
  • 9
  • 44
  • 79

3 Answers3

4

Which characters (or sequence of characters) am I allowed to use to combine two Prolog atoms?!

What you are asking here for, is the entire operator syntax definition of Prolog. To get the very full answer to this, please refer to the tag iso-prolog for full information how to obtain the Prolog standard ISO/IEC 13211-1.

But as a short answer to start with:

Prolog syntax consists of

  1. functional notation, like +(a,b), plus

  2. a dynamically redefinable operator syntax, plus

  3. some extra.

It seems you want to know which "characters" can be used as operators.

The short answer is that you can use all atoms Op that succeed for current_op(Pri,Fix,Op). So you can ask dynamically, which operators are present:

?- current_op(Pri, Fix, Op).
   Pri = 1, Fix = fx, Op = ($)
;  Pri = 1150, Fix = fx, Op = (module_transparent)
;  Pri = 700, Fix = xfx, Op = (=@=)
;  Pri = 700, Fix = xfx, Op = (@>=)
;  Pri = 700, Fix = xfx, Op = (>=)
; ... .

All those operators can be used in the specified manner, as pre-, in-, or postfix with the indicated priorities. Some of these operators are specific to SWI, and some are defined by the standard. Above, only @>= and >= are standard operators.

Most of the operators consist of the graphic characters #$&*+-./:<=>?@^~ only or of letters, digits and underscores starting with a lower case letter. There are two solo characters !; and then there are ,| which are even more special. Operator names that are different to above need quoting - you rarely will encounter them.

To see how operators nest, use write_canonical(Term).

The long answer is that you are also able to define such operators yourself. However, be aware that changing the operator syntax has often many implications that are very difficult to fathom. Even more so, since many systems differ in some rarely used configurations. For example, the system you mentioned, SWI differs in several ways.

I'd suggest to avoid defining new operators until you have learned more about the Prolog language.

false
  • 10,264
  • 13
  • 101
  • 209
3

let's see what's inside X = Y:Z

?- display( X = Y:Z ).
=(_G3,:(_G1,_G2))
true.

then we have a nested structure, where functors are operators.

An operator is an atom, and the rule for atom syntax says that we have 3 kind to consider:

  • a sequence of any printable character enclosed in single quote
  • a sequence of special characters only, where a special character is one of `.=:-+*/><#@~? (I hope I have found all of them, from this page you can check if I forgot someone !)
  • a sequence of lowercase/uppercase characters or the underscore, starting with a lowercase character

edit

A functor (shorthand for function constructor, I think, but function is misleading in Prolog context) it's the symbol that 'ties' several arguments. The number of arguments is named arity. In Prolog a term is an atomic literal (like a number, or an atom), or a recursive structure, composed of a functor and a number of arguments, each being a term itself (at least 1).

Given the appropriate declaration, i.e. op/3, unary and binary terms can be represented as expressions, like that one you show.

An example of operator, using the : special char, is ':-'

member(X,[X|_]).
member(X,[_|T]) :- member(X, T).
CapelliC
  • 59,646
  • 5
  • 47
  • 90
  • For a more portable solution to look into the structure of a term without using operator syntax, you can use the ISO Prolog standard `write_canonical/1` predicate. – Paulo Moura Oct 10 '13 at 20:08
  • Thanks Paulo, you're right. I was acquainted to use write_canonical/1, just this morning (or yesterday?) I noticed Jan used display/1, that I didn't known. It's far easier to remember than write_canonical... – CapelliC Oct 10 '13 at 20:14
  • first of all, thanks for your very useful comments! they helped me a lot! If I understand it right, the ":"-character is a functor in the example above?! And in this case the functor (what is a functor exactly?!) is the operator, or?? Now one question remains: Which other characters am I allowed to use like in the example, except ":". – mrbela Oct 11 '13 at 10:23
  • The `:` is not a "special" char, as you write. It is a graphic character like `#$&*+-./:<=>?@^~` – false Oct 11 '13 at 15:48
  • There are a lot of "special" characters for operators – false Oct 11 '13 at 18:43
1

The O.P., said (and I quote):

Sometimes I see terms like: X = a:b or X = a-b

I can do requests like X = Y:Z and the compiler unifies Y with a and Z with b, as expected.

Now my answer: Which characters (or sequence of characters) am I allowed to use to combine two Prolog atoms?!

The short answer is Pretty much whatever you want (provided it is an atom).

The longer answer is this:

What are seeing are infix (x infix_op b), prefix (pfx_op b) and suffix (b sfx_op ) operators. Any structure with an arity of 2 can be an infix operator. Any structure with an arity of 1 can be a prefix or suffix operator. As a result, any atom may be an operator.

Prolog is parsed via a precedence driven, recursive descent parser (written in Prolog, naturally). Operators are defined and enumerated, along with their precedence and associativity in the operator/3 predicate. Associativity has to do with how the parse tree is constructed. An expression like a - b - c could be parsed as ( a - ( b - c ) ) (right-associative), or ( ( a - b ) - c ) (left-associative).

Precedence has to do with how tightly operators bind. An expression like a + b * c binds as ( a + ( b * c ) not because of associativity, but because '*'/2 (multiplication) has higher precedence that '+'/2 (addition).

You can add, remove and change operators to your heart's content. Not that this gives you a lot of room to shoot yourself in the foot by breaking prolog's syntax.

It should be noted, however, that any operator expression can also be written via ordinary notation:

a + b * c

is exactly identical to

'+'( a , '*'(b,c) )
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
  • There is no reason to quote `+` or `*` in `+(a, *(b,c))` – false Oct 11 '13 at 19:50
  • Quoting the atom doesn't hurt and it can improve comprehension. *functor/arity* is a normal way of indicating predicate or structure name and arity, as in 'foo/2'. It's not prolog syntax: `'*'/2` means "the predicate or structure named `*` with an arity of 2. – Nicholas Carey Oct 11 '13 at 21:03
  • The standard way is to write brackets when the functor is an operator. as I indicated. The quoting used to be (~30 years ago) a convention to disable operators, but it has never caught on. – false Oct 11 '13 at 21:25