I can make expressions such as “if <cond> then <exp1> else <exp2>” parse, by declaring “if” as a prefix operator, and “then”, “else” and “elseif” as infix operators. But some programming languages allow the “then” to be omitted, so programmers can type “if <cond> <exp1> else <exp2>”. Is there a way of declaring operators in Prolog in such a way that this would parse?
I hesitate to say “no” but I don’t see a way to do it with Prolog’s op/3
, which I think is what you’re asking. I see how to do <exp1> if <cond> else <exp2>
, which is something like this:
:- op(600, xfy, if).
:- op(610, xfy, else).
?- X = 3 if foo else bar, write_canonical(X).
else(if(3,foo),bar)
X = 3 if foo else bar.
I tried to use fx
and xfy
with if
and else
, but doing so seems to lead to two things sitting next to each other with nothing combining them, something akin to (if foo) (3 else bar)
but the two things cannot be juxtaposed without some operator to combine them. Of course, comma would do, but then you must parenthesize since otherwise Prolog wants to solve the else part as a goal:
|: :- op(600, fx, if).
|: :- op(610, xfy, else).
|: % user://2 compiled 0.00 sec, 0 clauses
true.
?- X = if 3.
X = if 3.
?- X = if bar 3 else 4.
ERROR: Syntax error: Operator expected
ERROR: X = if bar
ERROR: ** here **
ERROR: 3 else 4 .
?- X = if bar, 3 else 4.
ERROR: Undefined procedure: (else)/2 (DWIM could not correct goal)
?- X = (if bar, 3 else 4), write_canonical(X).
','(if(bar),else(3,4))
X = (if bar, 3 else 4).
This doesn’t look satisfactory to me.
If the syntax is that important to you, it may be better to use DCGs to parse text. That is more work up-front but you’ll get a lot more flexibility about your language down the road, if this isn’t the only change you want to make.
There is a simple no-go for Prolog syntax: it does not allow for two non-operators to be adjacent. Thus, the answer is no. More in general, operators are great in adding domain specific languages to Prolog and using domain specific languages is one of the great advantages of Prolog. However, this assumes the language can be designed from scratch and you can come up with something that suits Prolog and your domain. Prolog operators are not very well suited to turn expressions from other concrete syntaxes into valid Prolog.
In some cases you can make users happy with a pure Prolog DSL that has some clear relation to an externally defined language. In others you can use SWI-Prolog’s quasi quotation syntax to embed arbitrary languages (but it requires some work and is not portable).