Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What about Adding (*->)/2 to DCG?

40 views
Skip to first unread message

Jan Burse

unread,
Feb 7, 2015, 11:59:29 AM2/7/15
to
Just a thought. Adding (*->)/2 to the DCG
standard would be nice. I have the feeling
that it could be useful in the Mini Isabelle
Clones Command language.

Made a little check, SWI-Prolog supports it:

Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.1.28)
Copyright (c) 1990-2014 University of Amsterdam, VU Amsterdam


?- [user].
p --> (q *-> r; s).
|:
true.

?- listing(p//0).
p(A, C) :-
( q(A, B)
*-> r(B, C)
; s(A, C)
).

true.

Looking at the newest ISO DCG draft(*), I don't
find it. But I guess it would do as an implementation
specific realization?

Anybody already compiled a list that compares which
Prolog supports the soft cut conditional in DCG
and which one not?

Bye

(*)
DCGs, DIN Draft 2014-08-31
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dcgs/dcgsdin140831.pdf

I didn't find any comments on DCG document that
mentions the soft cut condition (*->)/2 in connection
with DCG either. But I might be wrong.


Jan Burse

unread,
Feb 7, 2015, 12:17:23 PM2/7/15
to
Just thinking about a total new way of implementing
DCG. How about a table driven DCG, where the DCG
conversion is driven by a similar meta information
as the body conversion?

Body conversion is when a goal X is wrapped as
call(X). It seems that in SWI-Prolog (->)/2 and
(*->)/2 behave similar in this respect:

The (->)/2 connective:

?- [user].
p(X) :- (X -> r; s).
p(X) :- (q -> X; s).
p(X) :- (q -> r; X).

?- listing(p/1).
p(A) :-
( call(A)
-> r
; s
).
p(A) :-
( q
-> call(A)
; s
).
p(A) :-
( q
-> r
; call(A)
).

The (*->)/2 connective:

?- [user].
q(X) :- (X *-> r; s).
q(X) :- (q *-> X; s).
q(X) :- (q *-> r; X).

?- listing(q/1).
q(A) :-
( call(A)
*-> r
; s
).
q(A) :-
( q
*-> call(A)
; s
).
q(A) :-
( q
*-> r
; call(A)
).

So in case body conversion is driven by some meta
information, it could eventually also be used to drive
the DCG transformation, thus allowing to add things
like (*->)/2 freely for any end-user, who is able
to use the meta information API(*).

Bye

(*)
In Jekejeke Prolog the corresponding meta information is
currently the predicate property sys_body/0 and sys_rule/0.
For the DCG problem, I guess would need to respect sys_body/0
together with the meta_predicate/1 predicate property. Or
some such.

Jan Burse schrieb:

Ulrich Neumerkel

unread,
Feb 7, 2015, 8:14:11 PM2/7/15
to
Jan Burse <janb...@fastmail.fm> writes:
>Just a thought. Adding (*->)/2 to the DCG
>standard would be nice. I have the feeling
>that it could be useful in the Mini Isabelle
>Clones Command language.

You can add such constructs as an implementation specific extension.

Before adding (;)//2 resp. (*->)//2 or if//3 as a grammar control
construct to DCGs, the corresponding control construct (;)/2 (*->)/2
or if/3 would need to be defined. There are all kinds of subtle
differences between implementations. In particular w.r.t. cuts
in If and Then ; the relation to 7.6.2 etc. I cannot see any
convergence there.

Jan Burse

unread,
Feb 8, 2015, 2:02:27 PM2/8/15
to
ulr...@mips.complang.tuwien.ac.at (Ulrich Neumerkel) schrieb:
The (;)/2 exists already:

7.14.4 (;)//2 – alternative

But for a (*->)/2 it would need some modding. Especially:

7.14.5 (;)//2 with (->)//2 – if-then-else


Ulrich Neumerkel

unread,
Feb 8, 2015, 3:12:57 PM2/8/15
to
Jan Burse <janb...@fastmail.fm> writes:
>ulr...@mips.complang.tuwien.ac.at (Ulrich Neumerkel) schrieb:
>> Jan Burse <janb...@fastmail.fm> writes:
>>> Just a thought. Adding (*->)/2 to the DCG
>>> standard would be nice. I have the feeling
>>> that it could be useful in the Mini Isabelle
>>> Clones Command language.
>>
>> You can add such constructs as an implementation specific extension.
>>
>> Before adding (;)//2 resp. (*->)//2 or if//3 as a grammar control
>> construct to DCGs, the corresponding control construct (;)/2 (*->)/2
>> or if/3 would need to be defined. There are all kinds of subtle
>> differences between implementations. In particular w.r.t. cuts
>> in If and Then ; the relation to 7.6.2 etc. I cannot see any
>> convergence there.
>
>The (;)/2 exists already:
>
> 7.14.4 (;)//2 – alternative

This is in analogy 13211-1 to

7.8.6 (;)/2 - disjunction and
7.8.8 (;)/2 - if-then-else

Jan Burse

unread,
Feb 9, 2015, 3:44:33 AM2/9/15
to
Hi,

If you would deal with it that simple, it would
be that simple. But the analogy is broken, although
13211-1 defines a behaviour for:

7.8.7 (->)/2 - if-then

The DCG draft leaves if-then unspecified:

7.14.12 ->//2 - if-then
The effect of (->)//2 in grammar rules except
in the first argument of an alternative (cf. 7.14.5)
shall be implementation dependent.

So although tony dodd(*) defined a behaviour
for (->)/2 the initial draft from tony dodd
was already screwed up in that he needed 3 clauses
to define (;)/2 and (->)/2 instead only 2 clauses.

And the current draft then got further botched,
since the reference implementation noew does not
support (->)/2 anymore, probably a coding error (**)
of the simple spec from tony dodd.

Bye

(*)
people.sju.edu/~jhodgson/wg17/d895.ps

(**)
I guess there is a confusion about T3, making it
the main entry point (for bodies), wheras T (for rules)
resp T2 (for bodies) are the main entry points in
Tony Dodds spec. Shame.

ulr...@mips.complang.tuwien.ac.at (Ulrich Neumerkel) schrieb:
> Jan Burse <janb...@fastmail.fm> writes:
>> ulr...@mips.complang.tuwien.ac.at (Ulrich Neumerkel) schrieb:
>>> Jan Burse <janb...@fastmail.fm> writes:
>>>> Just a thought. Adding (*->)/2 to the DCG
>>>> standard would be nice. I have the feeling
>>>> that it could be useful in the Mini Isabelle
>>>> Clones Command language.
>>>
>>> You can add such constructs as an implementation specific extension.
>>>
>>> Before adding (;)//2 resp. (*->)//2 or if//3 as a grammar control
>>> construct to DCGs, the corresponding control construct (;)/2 (*->)/2
>>> or if/3 would need to be defined. There are all kinds of subtle
>>> differences between implementations. In particular w.r.t. cuts
>>> in If and Then ; the relation to 7.6.2 etc. I cannot see any
>>> convergence there.
>>
>> The (;)/2 exists already:
>>
>> 7.14.4 (;)//2 â alternative
>
> This is in analogy 13211-1 to
>
> 7.8.6 (;)/2 - disjunction and
> 7.8.8 (;)/2 - if-then-else
>
>> But for a (*->)/2 it would need some modding. Especially:
>>
>> 7.14.5 (;)//2 with (->)//2 â if-then-else
>>
>>

Jan Burse

unread,
Feb 9, 2015, 3:52:10 AM2/9/15
to
Jan Burse schrieb:
> So although tony dodd(*) defined a behaviour
> for (->)/2 the initial draft from tony dodd
> was already screwed up in that he needed 3 clauses
> to define (;)/2 and (->)/2 instead only 2 clauses.

Tony dodd's 3 clauses were:

T2((a->b;c), V1, V2)
:: T2(a, V1, V3) -> T2(b, V3, V2); T2(c, V1, V2)
T2((a;B), V1, V2)
:: T2(a, V1, V2); T2(b, V1, V2). /* a not _->_ */
T2((a->b), V1, V2)
:: T2(a, V1, V3) -> T2(b, V3, V2).

But the following 2 clauses do also the job:

T2((a;B), V1, V2)
:: T2(a, V1, V2); T2(b, V1, V2).
T2((a->b), V1, V2)
:: T2(a, V1, V3) -> T2(b, V3, V2).

And adding (->*)/2 (both as soft if-then-else and
as soft if-then) is as simple as adding:

T2((a*->b), V1, V2)
:: T2(a, V1, V3) *-> T2(b, V3, V2).


Ulrich Neumerkel

unread,
Feb 9, 2015, 4:30:04 PM2/9/15
to
Jan Burse <janb...@fastmail.fm> writes:
>Hi,
>
>If you would deal with it that simple, it would
>be that simple. But the analogy is broken, although
>13211-1 defines a behaviour for:
>
> 7.8.7 (->)/2 - if-then
>
>The DCG draft leaves if-then unspecified:

(->)/2 is the source of many bugs in Prolog. After all,
( false -> false ) is false and not true ; further
( A -> B ) must never be the result of some transformation.
Also (;)/2 has many problems similar to cut, due to (->)/2.


Ulrich Neumerkel

unread,
Feb 9, 2015, 4:47:48 PM2/9/15
to
Jan Burse <janb...@fastmail.fm> writes:
>And adding (->*)/2 (both as soft if-then-else and
>as soft if-then) is as simple as adding:
>
>T2((a*->b), V1, V2)
> :: T2(a, V1, V3) *-> T2(b, V3, V2).

No, it means that first of all *-> has to be defined.

Jan Burse

unread,
Feb 10, 2015, 3:06:05 AM2/10/15
to
ulr...@mips.complang.tuwien.ac.at (Ulrich Neumerkel) schrieb:
Well, (*->)/2 is defined. In most Prolog systems.
In SWI-Prolog, in Jekejeke Prolog:

Test Case 1:

?- [user].
p(1).
p(2).
p(3).

Yes
?- p(X) *-> write(X), nl; write('none'), nl.
1
X = 1 ;
2
X = 2 ;
3
X = 3

Test Case 2:

?- [user].
q(_) :- fail.

Yes
?- q(X) *-> write(X), nl; write('none'), nl.
none
Yes

So question is: Under the assumption(*) that we have
(*->)/2 how would we add (*->)//2 (as an if-then-else
and as an if-then) to DCG?

Bye

(*)
Title of the post: "What about Adding (*->)/2 to DCG?"
Assumes that (*->)/2 is already there.


Jan Burse

unread,
Feb 10, 2015, 3:14:14 AM2/10/15
to
ulr...@mips.complang.tuwien.ac.at (Ulrich Neumerkel) schrieb:
>> The DCG draft leaves if-then unspecified:
> (->)/2 is the source of many bugs in Prolog. After all,
> ( false -> false ) is false and not true ; further
> ( A -> B ) must never be the result of some transformation.
> Also (;)/2 has many problems similar to cut, due to (->)/2.

What bugs in Prolog? Why must (A->B) NEVER be the result
of some transformation?

I find a bug without transformation, i.e. not related for
example to DCG, related to the mere fact of attempting
simplification of goals(*):

(! -> fail), true; true.

So the above bug can happen in everyday queries, without
DCG involved. The following simplification doesn't work
on the above goal, and would change the behaviour:

A, true ~~> A

I don't know yet what would be the best workaround,
but it seems to be related to the goal simplification
per se and not to transformations from DCG to goals.

Bye

(*)
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/05_run/15_stdy/07_compliance/04_discrepancies/03_simplify.html

Ulrich Neumerkel

unread,
Feb 10, 2015, 11:24:59 AM2/10/15
to
Jan Burse <janb...@fastmail.fm> writes:
>ulr...@mips.complang.tuwien.ac.at (Ulrich Neumerkel) schrieb:
>> Jan Burse <janb...@fastmail.fm> writes:
>>> And adding (->*)/2 (both as soft if-then-else and
>>> as soft if-then) is as simple as adding:
>>>
>>> T2((a*->b), V1, V2)
>>> :: T2(a, V1, V3) *-> T2(b, V3, V2).
>>
>> No, it means that first of all *-> has to be defined.
>>
>
>Well, (*->)/2 is defined. In most Prolog systems.
>In SWI-Prolog, in Jekejeke Prolog:
>Test Case 1:
...
>Test Case 2:

There are implementations of it, and now two test cases.
However, I cannot see any definition that can be used
as a reference. For SWI at least, you would need to indicate
the precise version and all the modules loaded.

>So question is: Under the assumption(*) that we have
>(*->)/2 how would we add (*->)//2 (as an if-then-else
>and as an if-then) to DCG?

Too hypothetical given the actual situation:

(*->)//2 was added in 2002 to SWI. SWI does not have fully
conforming control constructs. Nor does it advertise to be fully
conforming nor advertise to plan to become fully conforming.
So differences are unlikely to be reported and identified. See
"Errors of call/1" in
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/SWI7_and_ISO

And it is similar for "most" of the other systems that
provide (*->)/2, except GNU Prolog which added (*->)/2 very
recently.

In SICStus if/3 and if//3 were added prior to 0.7 in 1990 and
SICStus has fully conforming control constructs, and does
self-declare as conforming.

Similarly IF.


(Originally, the construct has been introduced sometime prior
to 1985 as soft cut.)

Jan Burse

unread,
Feb 10, 2015, 1:51:06 PM2/10/15
to
Hi,

ulr...@mips.complang.tuwien.ac.at (Ulrich Neumerkel) schrieb:
> And it is similar for "most" of the other systems that
> provide (*->)/2, except GNU Prolog which added (*->)/2 very
> recently.

Change in GNU Prolog version 1.4.1:
* add soft cut control construct and its associated operator *->

Change in GNU Prolog version 1.4.2:
* fix a bug with *-> containing ! in the test part (! was not local to
the test)

http://www.gprolog.org/NEWS

> (*->)//2 was added in 2002 to SWI. SWI does not have fully
> conforming control constructs. Nor does it advertise to be fully
> conforming nor advertise to plan to become fully conforming.
> So differences are unlikely to be reported and identified. See
> "Errors of call/1" in
> http://www.complang.tuwien.ac.at/ulrich/iso-prolog/SWI7_and_ISO

I guess SWI-Prolog wants to offer a lot of checks
to the end-user. I noticed that body conversion
is sensitive to where the variable comes from:

The following works:

?- [user].
p(X) :- (q *-> X; r).

The following doesn't work:

?- [user].
p :- (q *-> _; r).

Not sure whether bug or feature.

Bye

Ulrich Neumerkel

unread,
Feb 10, 2015, 2:32:52 PM2/10/15
to
Which means that failure-slices cannot be executed directly. It
starts like this.
0 new messages