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

Bootstrapping conformity tests

167 views
Skip to first unread message

Ulrich Neumerkel

unread,
May 23, 2018, 2:48:59 AM5/23/18
to
burs...@gmail.com writes:
>Dont tell me your conformance test suite cannot
>be converted in a set of such goals.

Any test case with the word "wait" in some of the results cannot be
observed with a test harness you suggest.

Here are cases, where waiting is (one of) the expected behaviours:

http://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing#3

http://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing#214
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing#126

In #3 waiting is not essential for conformity, but still it is needed
to understand the differences between systems. This may show when you
are parsing invalid Prolog text like ") real(thing)." Some systems miss
the real(thing) and some don't.

In #214, #126 waiting is the expected behaviour.

With with_input_from/2 and similar predicates, you are testing another
Prolog text which ends in EOF. So you would get syntax errors for both.

burs...@gmail.com writes:
>Ulrich Neumerkel wrote:
>"You are suggesting using Prolog to store the data. That means,
>that a conforming system is needed to read such facts. One more
>link in the chain to break."
>
>To the best of my knowledge, this is not a great
>obstacle. For example if you test reading, you can
>place your test case into Prolog atom:
>
>Here is a test case for with the vertical bar in it:
>
>runner:case(read, 1, stream_read, 'ISO 6.3.3.1, XLOG 4') :-
> catch(with_input_from(atom('X = |.'), read(_)), error(E,_), true),
> E == syntax_error(cannot_start_term).

To make this test case into a test for conformity, you need ...

1mo, a system with a parser that is able to conformingly parse the atom
which holds the Prolog text to be parsed. Think of all the difficulties
with escape syntax when the Prolog text contains ' or \

2do, an implementation of with_input_from/2. There are many
situations when such is unavailable. Think of O-Prolog. For me, it is
sufficient to paste (manually) #1 to conclude that syntax has a problem
and thus I can stop looking into it.

3tio, to generalize the test case. It is too specific. cannot_start_term
is your own convention.

burs...@gmail.com

unread,
May 23, 2018, 3:54:45 AM5/23/18
to
Wait is a top level phänomenom, it has nothing to
do with ISO, you dont need to test it. What you
need to test are the iso production rules.

quoted token (* 6.4.2 *)
= Single quote char (* 6.5.5 *),
{ Single qyuoted item (* 6.4.2 *) } ,
Single quote char (* 6.5.5 *) ;

I have also a "wait" in the toplevel:

?- X = '\

But then there are different futures:

Future 1:

?- X = '\

Error: Illegal end of line in string.

^

Future 2:

?- X = '\
'.
X = ''

Testing these futures with with_input_from/2 is
no problem. You get exactly the same results as in
the top-level. The "wait" can be infered in that
adding futures gives different results.

?- with_input_from(atom('X = ''\\\n'), read(_)).
Error: Single quoted string not closed.
^
read/1
with_input_from/2

?- with_input_from(atom('X = ''\\\n\n'), read(_)).
Error: Illegal end of line in string.
^
read/1
with_input_from/2

?- with_input_from(atom('X = ''\\\n''.'), read(_)).
Yes

If there were no "wait", the futures wouldn't
change the result. I guess you are halucinating
and confused about some wait, which doesn't exist

as a test case. You need to test the ISO production
rules not some other nonsense.

burs...@gmail.com

unread,
May 23, 2018, 4:03:39 AM5/23/18
to
Your "wait" is only result that you test
with some top-level and not with some
harness.

The example with_input_from/2 uses the same
read(_) predicate as is used in the top-level.
But it uses memory streams.

There can be differences from Prolog system
to Prolog system, since the reader might
detect that it has a console stream in

front, or the top level might use something
different than reead(_), etc.. etc.. But my
guess is that the top-level is out of

scope of ISO core standard. And you shouldnt
either formulate test cases in terms of the
top-level, nor test top-level specific

stuff. A web server Prolog interpreter can
very well come headless without a top-level.
The syntax of the ISO core is more

for Prolog texts, not so much for the top-level.

Ulrich Neumerkel

unread,
May 23, 2018, 4:18:55 AM5/23/18
to
burs...@gmail.com writes:
>What you need to test are the iso production rules.

That is what you want. But this particular conformity test is about
syntax - everything related to it. Both reading, writing, and observing
results. You need all of this to, e.g., implement a top-level loop.

>Testing these futures with with_input_from/2 is
>no problem. You get exactly the same results as in
>the top-level. The "wait" can be infered in that
>adding futures gives different results.

You need infinitely many test cases to test what is done with a
single test. For finite conformity tests, this is a problem.
There are 126 test cases where waiting was or still is of relevance.
Just "grep wait" in the html-file.

(Note that you did not respond to all the other points made)

burs...@gmail.com

unread,
May 23, 2018, 4:21:30 AM5/23/18
to
Talking about "observable" your 22 May 2018 post else-
wheree. For testing the only observable thing
should be roughly:

- Input a finite stream of n-characters, after
the n-th character the stream should yield EOF.
- Output abstract term so and so is accepted,
and stream is at position so and so.
- Or no abstract term is accepted

For practial use, like tolerant error handling
we would like to add "or no abstract term is
accepted and stream is at position so and so."

But again that would be optional for a Prolog
processor. In the top-level this is very important
for ergonomics, but a for a Prolog text,

I guess a Prolog processor is allowed to give up
from the first error. Also this implies that
in "observable" there is no "wait"

nonsense included.

burs...@gmail.com

unread,
May 23, 2018, 4:25:43 AM5/23/18
to
This means the error is also irrelevant. I think
ISO doesn't define syntax errors. So you would
of course not test a cannot_start_term in

a more general test suite. So far I don't know
of a standardization of syntax error terms.
All that is observable is a yes or no.

No "wait" nonsense, no syntax error terms, no
nothing. Just the bare bone.

burs...@gmail.com

unread,
May 23, 2018, 4:46:02 AM5/23/18
to
The wait appears in the console, since
the console stream is blocking. You can
imagine it being a lazy data structure,
but has nothing to do with testing syntax.

In the end, the input will be also stream
of n-characters, means a text stream. There
is only an accidential occurence, that most
console streams are blocking for user

interaction. But this user interaction even
doesn't mean that the junks the console stream
sees, is free of newlines. For example in
my console I can also enter multiple lines,

for example by ccopy paste, and then submit them
with hitting the carriage return keyboard, which
will add a further newline to the multiple
lines. Many graphical consoles can do that,

when they also have copy paste. If you paste
multiple lines, the wait will completely
disappear. That is what confuses SWI-Prolog
sometimes. There is an error somewhere with tabs

which is very annoying. You can make a test
by yourself, take this multiline input. Namely
a definition of a predicate app/3 (append):

app([X|Y], Z, [X|T]) :-
app(Y, Z, T).
app([], X, X).

If between the head and the body of the first
clause, the alignment is 3 spaces everything
works fine, except that the SWI-Prolog "|:"
get srambled a little at the end:

?- [user].
|: app([X|Y], Z, [X|T]) :-
app(Y, Z, T).
|: app([], X, X).|:
|:
% user://1 compiled 0.00 sec, 2 clauses
true.

?- app(X,Y,[1,2,3]).
X = [1, 2, 3],
Y = [] ;
X = [1, 2],
Y = [3] .

Now try the same with a tab, input is now
as follows:

app([X|Y], Z, [X|T]) :-
app(Y, Z, T).
app([], X, X).

The result is now as follows, there goes something
wrong with the tab:

?- [user].
|: app([X|Y], Z, [X|T]) :-
.app(Y, Z, T).
app([], X, X).|:
ERROR: user://1:9:0: Syntax error: Operator expected
|:

The Mac interface of SWI-Prolog is much more buggier.
You cannot paste multilines at all. It will only
read the first line. But I guess this is all none
of business of ISO. But just to

show you how you can infinitely expand the testing,
if you add top-level, console specific issues to it.
You get even platform dependency.

Bye

I opened the Windows issue here:
https://github.com/SWI-Prolog/swipl-devel/issues/301

On the Mac there are much more ergonomics problems.

burs...@gmail.com

unread,
May 23, 2018, 4:50:20 AM5/23/18
to
So my suggestion, weed out console specific
test cases, especially those that fail, and
raise issues at the corresponding Prolog systems.

Try to get a more bare bone conformity test
suite, that is only based on the n-character
input paradigma. Try to publish it as Prolog code.

I guess its difficult for the 4-8 Prolog systems
that are anyway dead. How will they ever have
a with_input_from/2 predicate, when they are $

already many years dead, cold stone dead?

Ulrich Neumerkel

unread,
May 23, 2018, 4:59:09 AM5/23/18
to
burs...@gmail.com writes:
>Your "wait" is only result that you test
>with some top-level and not with some
>harness.

This is a misunderstanding. In

http://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing

an actual harness **is** used, strictly speaking:

> The Query entry below including a newline character at the end is sent
> as input to read(X),X. or read(X),X, read(Y),Y. The comment /**/ is
> replaced by the last preceding entry not containing /**/ .

In a conforming processor you must be able to execute read(X),X *somehow*.
Maybe by adding an auxiliary predicate r :- read(X),X. should no
top level loop be available.

However, many Prolog systems do provide a top level loop with essentially
that very functionality. So in these system, above harness is not needed.

And, yes, some systems' read/1 and the "top level" reader is different. B
is such an example. So these do need the harness. Or at least for
cases where a difference may occur.

burs...@gmail.com

unread,
May 23, 2018, 5:56:50 AM5/23/18
to
Yes you are possibly true about B-Prolog. But what is
the scope of ISO core standard, and its syntax? Its
neither testing special read predicates, nor testing
top-level specific behaviour.

I don't see any clause that would define it, in the
ISO core standard specification. Thats a problem of
the B-Prolog system, if it has a special top-level.
Even such old Prolog predicates that can poll the

console like get0(_) or influence the console are not
any more part of the ISO core standard. There is only
peek_byte/[1,2] etc.., and peek_code/[1,2] and
peek_char/[1,2] etc...

You might want to test these predicates in connection
with a console. But again I think this would be
also out of scope. The only notion in ISO core standard
is binary stream and text stream. Even behaviour of

peek_byte/[1,2], peek_code/[1,2] and peek_char/[1,2] you can
test with the harness with_input_from/2:
- For peek_byte/[1,2], etc.., input n-bytes stream,
with after n-th byte there is EOF.
- For peek_code/[1,2] and peek_char/[1,2], etc..
input n-characters stream, with after n-th character
there is EOF.
- For bytes the effect is some result from the
predicate an a new byte position.
- For character the effect is some result of the
predicate an a new character position.

Still no wait perceivable, since what you observe
is only what is arguments of the predicates. Input
and output paraemter, and the implicit or explicit
stream. You cannot observe some wait, this is only

business of the stream, none of the business of some
of the read predicates. The with_input_from/2 predicate
from my library(charsio) allows both providing binary
input and text input. For binary input you just say

bytes([97,98,99]) instead of atom('abc'):

For predicates that expect text streams:

?- with_input_from(atom('abc'), peek_code(X)).
X = 97 ;
No

?- with_input_from(bytes([97,98,99]), peek_code(X)).
Error: Can't apply arguments to method sysPeekCode(java/io/'Reader').
peek_code/1
with_input_from/2

For predicates that expect binary streams:

?- with_input_from(bytes([97,98,99]), peek_byte(X)).
X = 97 ;
No

?- with_input_from(atom('abc'), peek_byte(X)).
Error: Can't apply arguments to method sysPeekByte(java/io/'InputStream').
peek_byte/1
with_input_from/2

Ulrich Neumerkel

unread,
May 23, 2018, 6:14:27 AM5/23/18
to
burs...@gmail.com writes:
>Yes you are possibly true about B-Prolog. But what is
>the scope of ISO core standard, and its syntax? Its
>neither testing special read predicates, nor testing
>top-level specific behaviour.

Top level behaviour is out of scope of 13211-1 qua 1 Scope, Note f. But
executing read(X), X is not out of scope. Therefore B is fine to make
something slightly different with its top level. However, it has to conform
when read(X), X is used.

>You might want to test these predicates in connection
>with a console. But again I think this would be
>also out of scope. The only notion in ISO core standard
>is binary stream and text stream.

See

| 3.160 source: A physical object from which a processor
| inputs data, for example a file, terminal, or interprocess
| communication channel (see 7.10.1).

So terminal and interprocess input is explicitly included. Also,
13211-1 talks about "interactive" programs a couple of times.

In conclusion, waiting is part of behaviour that can be
observed (and expected) in standard conforming programs that
use appropriate sources.

burs...@gmail.com

unread,
May 23, 2018, 7:15:43 AM5/23/18
to
But you cannot "observe" waiting at the receiving
end of a stream. With or without wait shouldn't
make a difference in the result.

If you have a stream 'abc<wait>def'

and a stream 'abcdef'

There is absolutely no observable difference
for what parsing should do. I still think
you are halucinating and confused.

The standard says:

3.160 source. A pysical object from which a
processor **inputs data**, for example a file,
terminal, or interprocess communication channel.

But there is no <wait> input data. Can you show
me any code, using only ISO core standard means,
that would detect <wait> input data?

This is impossible because there is no <wait>
input data. This is something that is business of
the source when it produces input data,

but the input data is free of any <wait>. What
is the byte code of <wait> or the character code
of <wait>? This is complete nonsense,

there is no such byte code or character code.
All you will see is the following:

- For peek_byte/[1,2], etc.., input n-bytes stream,
with after n-th byte there is EOF.
- For peek_code/[1,2] and peek_char/[1,2], etc..
input n-characters stream, with after n-th character
there is EOF.

You cannot see anything else in input data
regularly. Only if you would have a peek_avail/1,
which would return some info if the stream is
waiting. But there is no such API.

You confuse the input data with the source.
The input data is not the source. The source can
be file, terminal or interproicess communication
channel, but the input data

is still binary stream or text stream. And these
streams presently have no peek_avail/1 API. You
can only notice <wait> went your streams provide
this information through their input data APIs.

Such an API is for example found in other Programming
Languages and Runtimes. But I don't see any such
API in the Prolog ISO core standard. It could be
helpful to code top-levels, but the binary

and text streams of the ISO core standard don't
provide it. What is missing in the ISO core standard,
and what might be even not supported by all
streams is the following:

"Returns an estimate of the number of bytes that can be read
(or skipped over) from this input stream without blocking by
the next invocation of a method for this input stream. The
next invocation might be the same thread or another thread.
A single read or skip of this many bytes will not block,
but may read or skip fewer bytes."
https://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#available%28%29

Thats even not a very health API, since it may
support polly loops programing style. A much better
API would be some that would use some async mechanism.
Its good that this didn't find its way into ISO core

standard. So definitely in ISO core standard there
is absolutely no notion of <wait>. Thats just a
halucination and confusion of yours. A wait inside
a source has nothing to do with the produced

input data. A Prolog system might have available() or
something similar and even use it somewhere, but this
has nothing to do with the ISO core standard. You
can test all read/write as if the input came from

a file, without any blocking in the source. One
way to do this easily is with_input_from/2 where the
file is replaced by a memory stream. So to allow
easy harnessing of small test cases,

but there is definitely no recognizable <wait>
in input data in ISO core standard.

burs...@gmail.com

unread,
May 23, 2018, 7:29:17 AM5/23/18
to
Ulrich, you are really a funny guy, and you make
me laugh a little bit. Show me a Prolog standard
code, which given a stream with 10 characters,

will detect whether the stream will do a "wait",
during reading these 10 characters. What do you
want to do, spawn another thread

and do some time measurements. There is even
not a standard for threads. And what if the stream
was just slow, and didn't wait.

Ok, show me such a code, that for an arbitrary
source with 10 characters input data can produce
yes/no if the source was waiting, and I will

end the debate. But still I think this wait is
phatamorgana which has nothing to do with builtins
of the ISO core standard and its streams,

especially the input data that is assumed from
a source. In such input data you cannot regularly
recognize a wait. You might have some such notion

in the source, like a blinking cursor, but this is
completely irrelevant. Already when you start
a read builtin, it will naturally wait:

Look see a wait (wait 1):

Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.14)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.

?- read(X).
|:

Look see another wait (wait 2):

Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.14)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.

?- peek_code(X).

Do you want to make a test harness that checks
for (wait 1) and (wait 2). Thats just plain carzy,
thats just a source which is working on producing

its input data. Nothing else. No relevance whatever
for the processing of input data.

burs...@gmail.com

unread,
May 23, 2018, 7:43:07 AM5/23/18
to
The "waiting" could be a small indicative that
there was either a get_code or a peek_code.
But usually from the test code, you know what

you did, whether there was a get_code or a
peek_code. So all that remains is testing whether
input data stream has a correct state after

the operation, like for example reading more,
and looking whether the positioning was correct.
But not all streams are repositionable and have

a queryable stream position. So all you can
do concerning a correct state after operation,
is to apply some common sense, and make a

couple of tests. The ISO core standard document
already gives a hint what these tests could be.
One example is this test:

runner:ref(read, 1, stream_read, 'ISO 8.14.1.4, ISO 6.3.3.1').
runner:case(read, 1, stream_read, 'ISO 8.14.1.4, ISO 1a') :-
with_input_from(atom('term1. term2. '), read(X)),
X == term1.
runner:case(read, 1, stream_read, 'ISO 8.14.1.4, ISO 1b') :-
findall(X, with_input_from(atom('term1. term2. '),
( read(_); read_line(X))), [_,X|_]),
X == 'term2. '.
https://github.com/jburse/jekejeke-samples/blob/master/jekdev/compliance/stream/read.p#L127

Note: read_line/1 is not ISO core standard, but you can
bootstrap it from get_code/1 plus a newline character
assumption. Its just a convenience here. But newline is
anyway not part of the above test case, so its a non-issue.

Another example is this test:

runner:ref(peek_char, 1, stream_text, 'ISO 8.12.2.4').
runner:case(peek_char, 1, stream_text, 'ISO 8.12.2.4, ISO 1') :-
with_input_from(atom('qwerty '), peek_char(X)),
X == q.
runner:case(peek_char, 1, stream_text, 'ISO 8.12.2.4, XLOG 1') :-
with_input_from(atom('qwerty '), ( peek_char(_),
get_char(X))),
X == q.
https://github.com/jburse/jekejeke-samples/blob/master/jekdev/compliance/stream/text.p#L82

burs...@gmail.com

unread,
May 23, 2018, 8:14:52 AM5/23/18
to
The only scenario I can imagine for a wait
test, is testing that a top-level terminal
doesn't do too much waits.

Like if you do too much look-ahead. But then
your top-level gets anyway unusable, if you
do unnecessary get_code and then peek_code,

instead only peek_code, because then the top-level
will not get its input data, and then the top-level
will just sit and wait and not do anything.

But you can test unnecessary get_code/1 by
with_input_from/2. About an uncessary peek_code/1
I am not sure. A read/1 can really be broken

this way. I am not sure whether the ISO core
standard defines this kind of errorneous behaviour
of a read/1. Its very difficult to define

unwanted peek_code/1 as unallowed and even test
it. The situation is expect to happen for example
in terminating period and comments, not so much

quoted atom tokens. In a quoted atom token, the
problem cannot appear since a quoted atom token
is ballanced by the other quote. So maybe a

compromise can be made:

- Its possibly already now possibly to weed
out test cases, that do not need a notion
of wait, like the quoted atom tokens.

They have anyway a balanced closing quote,
so there cannot be a superflous peek_code.
This test cases should be rewritten with

the help of with_input_from/2.

- On the other hand there is the unsatisfactory
situation, that for files and interprocess
communication, its possibly irrelevant

when there is a superflous peek_code,
except maybe in the terminal situation, or
even in some interprocess communication,

maybe invent a new with_input_from/2, lets
call it with_input_from2/2, that can measure
the peek ahead?

Thats how I would approach the problem, if it would
be really a nagging problem for me. Basically for
terminals this is a good strategy for implementors:

- Do not over peek the newline.

Ulrich Neumerkel

unread,
May 23, 2018, 8:48:59 AM5/23/18
to
burs...@gmail.com writes:
>But you cannot "observe" waiting at the receiving
>end of a stream. With or without wait shouldn't
>make a difference in the result.
>
> If you have a stream 'abc<wait>def'
>
> and a stream 'abcdef'

That's not the waiting that happens in the tests. There, only
the tester can observe waiting, not the program itself.

burs...@gmail.com

unread,
May 23, 2018, 11:48:37 AM5/23/18
to
Well its the same waiting like yours, for
example if the stream is 'abc\ndef...', and if
it is input in a terminal without copy paste,

then on the source side, this results is
'abc\n<wait>def...'. But on the input data
side its nevertheless 'abc\ndef...'.

You can check yourself SWI-Prolog:

Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.1)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.

?- abc
/* will wait here */

Thats exactly your <wait>: Namely the
system goes on a new line and the cursor
blinks, and nothing else happens. But on

the input data side its a no-op.

Same behaviour in GNU-Prolog:

GNU Prolog 1.4.4 (64 bits)
Compiled Apr 23 2013, 17:26:17 with /opt/local/bin/gcc-apple-4.2

| ?- abs
/* will wait here */

This happens for all Prolog systems, that do not
process the top-level by assuming a quary sits on
one line, and thus assuming they

can kind of read this one line, parse it and give
the result to the interpreter. This happens for all Prolog
systems that view the terminal more as a stream,

where they grab the abstract term from, by a more
general routine, than the just the line grabbing
describe as before.

Writing such a more general routine is a little
more difficult in the beginning, but as SWI-Prolog,
GNU-Prolog show, not impossible.

But again I consider this out of scope of an
ISO conformance test. For example if a Prolog
system throws an error already here, why not?

?- abc

The top-level is not specified in the ISO core
standard, and hence its up to the Prolog system
how the top-level is read, and whether it

accepts multi-line input or not. I am not defending
my own Prolog system. Jekejeke Prolog can also do
multi-line input. Only for many beginning

Prolog systems multi-line input can be more
challenging. For those Prolog systems that can
do multi-line input, its also not without pitfals.

For example this test case here is quite funny:

SWI-Prolog can do it:

?- read(X), write(X), nl. write(bar), nl.
write(bar),nl
X = (write(bar), nl).

GNU-Prolog can do it:

?- read(X), write(X), nl. write(bar), nl.
write(bar),nl

X = (write(bar),nl)

Jekejeke Prolog can do it:

?- read(X), write(X), nl. write(bar), nl.
write(bar),nl
X = (write(bar),nl)

What about other Prolog systems. Can they do it?
Should a conformance test suite test such
things, for the top level?

I dont say you have this one on your testing list.
But a full scope top-level (=Prolog REPL) testing,
can be infinitely expanded.

Are multiple readers on top of a stream even specified
in the ISO core standard?

burs...@gmail.com

unread,
May 23, 2018, 11:54:08 AM5/23/18
to
Basically each new reader is not allowed to
establish new buffering, otherwise the
example doesn't work.

Again its not an example on your list. But
the top-level itself is infinitely complex.
Just throw out and don't test wait,

only test the **essential**. And the **essential**
of the Prolog syntax is not the wait of
some top-level (=Prolog REPL).

Thats just nonsense, it should be possible
to capture the **essential** without an
artificial <wait> invention,

which is nowhere specified in the ISO
core standard.

burs...@gmail.com

unread,
May 23, 2018, 11:59:28 AM5/23/18
to
Surprise surprise, here is a system that cannot
do the previous test case:

ECLiPSe Constraint Logic Programming System [kernel threads]
Version 7.0 #36 (x86_64_nt), Sun Jan 28 10:18 2018
[eclipse 1]: read(X), write(X), nl. write(bar), nl.
.
syntax error: unexpected fullstop
| .
| ^ here

No (0.00s cpu)
[eclipse 2]: bar

Yes (0.00s cpu)
[eclipse 3]:

burs...@gmail.com

unread,
May 26, 2018, 4:53:18 AM5/26/18
to
Unfortunately you invented an expensive extra
parenthesis solution, which probably no system
implements:

Also Corr.3 of the ISO standard tries to define
the writing, especially how extra parenthesis
are set. But there are also different strategies

possible. By glossing over Corr.3
https://www.complang.tuwien.ac.at/ulrich/iso-prolog/WDCor3

It seems to me their approach is like this:

Current Cor.3 Proposal, expensive to implement (naive)
======================================================

But there it is only:
a) If Term is a variable
b) If Term is an integer
c) If Term is a float
d) If Term is an atom
e) If Term has the form ’ $VAR’ (N)
f) Else if Term has a principal functor
which is not a current Operator,
/* add some logic ( ) here for the arguments */
g) Else if Term has the form ' . '
/* add some logic ( ) here for the arguments */
h) If Term has a principal functor
which is an Operator

But the above f) and g) based enhencement is
not really what Prolog systems implement.
Usually the approach is much simpler, and
leads to less current_op lookup during unparsing.

You add the extra parentheses of course in
d) and h), you put some logic for the whole
expression in these unparsing production. You
decide there to put or not put extra parenthesis:

What Prolog implementations do (non-naive)
==========================================

The reality out there:
a) If Term is a variable
b) If Term is an integer
c) If Term is a float
d) If Term is an atom
/* add some logic ( ) here for the expr */
e) If Term has the form ’ $VAR’ (N)
f) Else if Term has a principal functor
which is not a current Operator,
g) Else if Term has the form ' . '
h) If Term has a principal functor
which is an Operator
/* add some logic ( ) here for the expr */

burs...@gmail.com

unread,
May 26, 2018, 4:56:58 AM5/26/18
to
Why is the Corr.3 solution expensive. Well it
requires for example when I write:

Clause f) of Term writing:

f(expr1,..,exprn)

That expr1,..,exprn are each analysed, i.e.
their functor is determined, an operator lookup
is done and it is decided whether parenthesis
are put. But the same analysis happens

again, if you go on to write each expr1,..,
exprn, when you call recursively the writing
routine. It happens again in h). So you do all
the work twice. You can put the check directly

Into Clause h) of Term writing:
expr

burs...@gmail.com

unread,
May 26, 2018, 5:07:17 AM5/26/18
to
You can check my source code how it is effectively
implemented, to minimize the operator lookup:

What Prolog implementations do (non-naive)
==========================================

The reality out there:
a) If Term is a variable
b) If Term is an integer
c) If Term is a float
d) If Term is an atom
/* add some logic ( ) here for the expr */
protected void writeAtom
https://github.com/jburse/jekejeke-devel/blob/master/jekrun/headless/jekpro/model/pretty/PrologWriter.java#L620

e) If Term has the form ’ $VAR’ (N)
f) Else if Term has a principal functor
which is not a current Operator,
g) Else if Term has the form ' . '
h) If Term has a principal functor
which is an Operator
/* add some logic ( ) here for the expr */
private boolean needsParen
https://github.com/jburse/jekejeke-devel/blob/master/jekrun/headless/jekpro/model/pretty/PrologWriter.java#L717

/* prefix unparse uses needsParen */
https://github.com/jburse/jekejeke-devel/blob/master/jekrun/headless/jekpro/model/pretty/PrologWriter.java#L1229

/* postfix unparse uses needsParen */
https://github.com/jburse/jekejeke-devel/blob/master/jekrun/headless/jekpro/model/pretty/PrologWriter.java#L1256

/* infix unparse uses needsParen */
https://github.com/jburse/jekejeke-devel/blob/master/jekrun/headless/jekpro/model/pretty/PrologWriter.java#L1295

Disclaimer: All code work in progress. Currently
the parser does not yet take module qualification into
account for operators, same the unparsers.

Modules are only taken into account by the unparser
for meta information, so that the pretty printing
spacing can be made. But I will probably

make some upgrades in the future, module qualification
might change the operator behaviour. But this
only considers modules, so dont worry...

burs...@gmail.com

unread,
May 26, 2018, 5:40:45 AM5/26/18
to
The below simple and efficient parren checks,
does also work for expressions that are not
case f) or case g) of the core standard.

It works for everything, it needs to carry around
a little context hint when invoking the unparser.
Just remember you need to be able to unparse
as well expressions such as the following:

Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.14)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.

?- X = (a+b)*(c+d), write_canonical(X), nl.
*(+(a,b),+(c,d))
X = (a+b)*(c+d).

But the algorithm to do that is darn simple.
Don't touch f) or g). Only modify h) (and
optionally d) for the operator escaping/
priority overiding). Works perfectly:

Jekejeke Prolog 2, Runtime Library 1.2.7
(c) 1985-2018, XLOG Technologies GmbH, Switzerland

?- X = (a+b)*(c+d), write_canonical(X), nl.
*(+(a,b),+(c,d))
X = (a+b)*(c+d)

Or as logicians tend to explain the matter.
They often depict the situation as follows,
all operators are in principle written with
parenthesis, like for example:

((p -> r) -> (q -> s))

Then there are rules to **omit** the parenthesis,
so that we are allowed to write it without
parenthesis:

(p -> s) -> q -> r

So you could first write an unparser that
always puts parenthesis for operators. And
then an improved unparser that **omits** the
parenthsis for operators, where possible.

Quiz: Where does this parenthesis omitting happen?

Answer: It can be easily done in case h) of the
core standard, not really the business of
case f) or g) of the core standard.

Here again the logician example:

Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.14)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.

?- write(((p -> r) -> (q -> s))), nl.
(p->r)->q->s

And the other system:

Jekejeke Prolog 2, Runtime Library 1.2.7
(c) 1985-2018, XLOG Technologies GmbH, Switzerland

?- write(((p -> r) -> (q -> s))), nl.
(p->r)->q->s

Ulrich Neumerkel

unread,
May 26, 2018, 9:26:31 AM5/26/18
to
burs...@gmail.com writes:
>Also Corr.3 of the ISO standard tries to define
>the writing, especially how extra parenthesis
>are set. But there are also different strategies
>possible. By glossing over Corr.3
>https://www.complang.tuwien.ac.at/ulrich/iso-prolog/WDCor3
>
>It seems to me their approach is like this:
>
>Current Cor.3 Proposal, expensive to implement (naive)

>But there it is only:
>a) If Term is a variable
>b) If Term is an integer
>c) If Term is a float
>d) If Term is an atom
>e) If Term has the form '$VAR'(N)
>f) Else if Term has a principal functor
...

You are reading neither Cor.3 nor WDCor3! There is
a1, a2, e1, e2, e3 which just escaped your attention...

Ulrich Neumerkel

unread,
May 26, 2018, 9:30:50 AM5/26/18
to
burs...@gmail.com writes:
>Why is the Corr.3 solution expensive. Well it
>requires for example when I write:
>
>Clause f) of Term writing:
>
> f(expr1,..,exprn)
>
>That expr1,..,exprn are each analysed, i.e.
>their functor is determined, an operator lookup
>is done and it is decided whether parenthesis
>are put. But the same analysis happens
>again, if you go on to write each expr1,..,
>exprn, when you call recursively the writing
>routine. It happens again in h). So you do all
>the work twice.

Please do not confuse a specification with an
actual implementation! There is no runtime
efficiency isssue in a specification. And,
there are even larger overheads in the
standard, requiring n^2 operations in stead
of just n.

Julio Di Egidio

unread,
May 26, 2018, 11:59:07 AM5/26/18
to
On Saturday, 26 May 2018 15:30:50 UTC+2, Ulrich Neumerkel wrote:
> burs...@gmail.com writes:
>
> >Why is the Corr.3 solution expensive.
<snip>
>
> Please do not confuse a specification with an
> actual implementation!

Yes, and ironic is that all you can offer to an implementer is conformance
tests...

Julio

Ulrich Neumerkel

unread,
May 26, 2018, 12:36:27 PM5/26/18
to
Julio Di Egidio <ju...@diegidio.name> writes:
>On Saturday, 26 May 2018 15:30:50 UTC+2, Ulrich Neumerkel wrote:
>> burs...@gmail.com writes:
>>
>> >Why is the Corr.3 solution expensive.
>> Please do not confuse a specification with an
>> actual implementation!
>
>Yes, and ironic is that all you can offer to an implementer is conformance
>tests...

What else are you thinking of?

Julio Di Egidio

unread,
May 26, 2018, 12:53:09 PM5/26/18
to
What else is needed, not what I am thinking. I am thinking tonight's party.

*A specification is needed, a good one*: not tests, leave the tests to where
they belong, i.e. to QA and after the fact. Indeed, you have an entire
community essentially copying form each other... Do you really think that's
(technically) sane? And do you think it's (just) a marketing problem that
Prolog is still pretty much unknown to the industry, despite e.g. the present
hype on AI? Smart contracts on blockchains are being written in all (stupid,
ad hoc) languages but any Prolog or Prolog-like, for instance...

Julio

burs...@gmail.com

unread,
May 26, 2018, 5:30:21 PM5/26/18
to
Well I can tell you a little secret. Since the
code is shorter, I guess a corresponding specification
would also get shorter.

It doesn't make sense to copy pasta some tests
into multiple clauses of the standard, when upon
reflection it would suffices to copy it only

into one clause. Remember:

level of ease, elegance, and efficiency
https://www.youtube.com/watch?v=uQrS4Byo-VU

burs...@gmail.com

unread,
May 31, 2018, 9:17:27 AM5/31/18
to
The name Bootstrapping conformity tests, already
indicates a mis thinking about conformity tests.
Currently you take Prolog systems, and look whether
their reaction can be interpreted as allowed.

This is completely wrong, the ISO core standard says:

5.1 Prolog processor
c) Reject any Prolog text or fails to conform to:
1) the requirements of this part of ISO/IEC 13211,
2) the implementation defined and implementation
specific features of the Prolog processor.

So you would need to check again the minimal
requirements, and what each implementation defined
(for the given Prolog system, strict/non-strict mode)
or specified as feature (for the given Prolog system,

strict/non-strict mode). So you would need a
full self declaration of each Prolog system
and test against it. Here is an example how such a
self declaration looks like from

ECLiPSe Prolog, namely:

ISO strict:
Specification of implementation defined features
Implementation specific features
http://eclipseclp.org/doc/bips/lib/iso_strict/index.html

ISO:
Specification of implementation defined features
Implementation specific features
http://eclipseclp.org/doc/bips/lib/iso/index.html

This means also, you cannot test all the dead Prolog
systems. Since they don't have such a self declaration
slip. These Prolog systems all don't belong on your
conformance test, if they don't provide such a slip:

Like 10 out of the 11 Prolog systems you have
tested. Only ECLiPSe Prolog has such a slip.

Ulrich Neumerkel

unread,
May 31, 2018, 11:40:31 AM5/31/18
to
burs...@gmail.com writes:
>The name Bootstrapping conformity tests, already
>indicates a mis thinking about conformity tests.
>Currently you take Prolog systems, and look whether
>their reaction can be interpreted as allowed.
>
>This is completely wrong, the ISO core standard says:
>
>5.1 Prolog processor
>c) Reject any Prolog text or fails to conform to:
>1) the requirements of this part of ISO/IEC 13211,
>2) the implementation defined and implementation
>specific features of the Prolog processor.
>
>So you would need to check again the minimal
>requirements, and what each implementation defined
>(for the given Prolog system, strict/non-strict mode)
>or specified as feature (for the given Prolog system,
>strict/non-strict mode). So you would need a
>full self declaration of each Prolog system
>and test against it.

That is an extremely laborious approach which would be taken if
formal certification is done. Instead, tests are performed.
In case it works, it's OK. Otherwise, the difference is
classified manually into

misinterpretation,
rejection,
write syntax deviation, and
extension.

Only extensions are permitted by 5.1. The three other
classes are all non-conformance. For users the their
impact is of of varying degree, write syntax deviations
are probably the least problematic once, then come rejections
which are relatively easy to detect.

> Here is an example how such a self declaration looks like from
>
>ECLiPSe Prolog, namely:

This self declaration is from 2018-01. After dicussions.

>This means also, you cannot test all the dead Prolog
>systems. Since they don't have such a self declaration
>slip.

If you mean by "dead", systems that did not update recently,
no. They all have a self-declaration.

A particularly explicit one is IF/Prolog. Please refer to the
manual! It's all online, and all is linked.

burs...@gmail.com

unread,
May 31, 2018, 1:39:25 PM5/31/18
to
But for example an implementation defined feature,
a feature that can exist in ISO strict, are bignums.
You do not test any bignums.

Nobody knows whether these Prolog systems, if they
have bignums in ISO strict, really have working
bignums in ISO strict.

Even not on the syntax level, we do not know anything
about these Prolog systems. At least I don't find
any bignum parsing and unparsing test cases.

What you show:
misinterpretations
rejections
write syntax deviations
extensions

Is a kind of test result classification. But the
tests are not "laborious" as you call it, in that
there is also a test case classification.

Well there are some footnotes here and then in your
web site. But this is a little poor. Every feature
from ISO-strict that has a possibility of an

implementation defined behaviour, has more or less
a reference number. But bignum is ISO strict, and
not ISO non-strict. You can check yourself:

7.11.1 Flags defining integer type 1
NOTE - The value of these flags is fixed
and implementation **defined.**

How would you test bignum. Some CLP(FD) with bignum
makes more sense. Should CLP(FD) test bignum on
their own, or rely on ISO core standard delivered

correct bignums, if a Prolog system has them?
bignum testing would also include testing the
bitset operations, in case you test not only syntax.

For syntax, I guess a few test cases would
be enough, like positive and negative bignum,
some border cases, etc.. You got these test cases,

that have to do with float range:

172 X is 10.0** -323, writeq(X).
173 1.0e-323=:=10.0** -323.

But how about bignums. Are they written
on a separate page?

> If you mean by "dead", systems that did not update recently,
> no. They all have a self-declaration.
> A particularly explicit one is IF/Prolog. Please refer to the
> manual! It's all online, and all is linked.

Link or it doesn't exist! I don't find a manual on
their web site. Do they have HTML splits online manual.
Maybe link directly to the ISO declaration. In ECLiPSe
Prolog such a link is possible.

Ulrich Neumerkel

unread,
May 31, 2018, 2:06:33 PM5/31/18
to
burs...@gmail.com writes:
>But for example an implementation defined feature,
>a feature that can exist in ISO strict, are bignums.
>You do not test any bignums.

Right, I don't. That would be another test.

> 7.11.1 Flags defining integer type 1
^
> NOTE - The value of these flags is fixed
> and implementation **defined.**

Note that the codex reads "type I" not "type 1"

For the moment, I do not see much reason into testing
unbounded integers. Are there systems displaying
differences?

>Should CLP(FD) test bignum on their own, or ...

That's even more ambitious. Yet, I do not see a need
to go through it case-by-case. Do you?

>I don't find a manual on their web site.

http://www.ifcomputer.de/dateien/refman.pdf

burs...@gmail.com

unread,
May 31, 2018, 4:59:04 PM5/31/18
to
No, no, I don't mean testing CLP(FD). I mean CLP(FD)
which depends on bignum, should it test the ordinary
bignums first on its own. Or rely on some others tests.

A component A depends on a component B.

Does the component B deliver a certificate. Or does
the component A have to certify B on itself? What
are the clients of the ISO core standard?

component A = CLP(FD)

component B = bignums from the core

Side remark: Testing CLP(FD) is not that difficult.
I did that. I wrote a whole suite for my CLP(FD).
You can see it here:

431 Test Cases for CLP(FD) & Co.
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/15_min/15_stdy/07_compliance/06_summary.html

If remeber well Markus Triska is also testing
his CLP(FD), or SWI-Prolog. Dunno exactly. Not
everybody is only testing baby stuff.

bignums of component B are of interest, but I
guess, they are viewed as, well, if small integers
work, than also big nums work?

burs...@gmail.com

unread,
May 31, 2018, 5:02:42 PM5/31/18
to
A test suite for CLP(B) is not yet available,
since it is still fresh. On the other hand the
CLP(FD) suite is already some years old.

j4n bur53

unread,
May 31, 2018, 5:10:50 PM5/31/18
to
I have also some testcases inside the CLP(FD) suite,
that test some extra bignum stuff. The ordinary bignum
stuff is covered by my core test suite,

but some extra bignum stuff is found here:


http://www.jekejeke.ch/idatab/doclet/prod/en/docs/15_min/15_stdy/07_compliance/09_results/02_misc/package.html?hash=numtheo

This one is an example extra bignum test for the
extra bignum stuff:

/* CLP(FD) 0.9.2, 1.2, XLOG 4 */
X is gcd(-12*2^100,-18*2^100),
X =:= 6*2^100.
/* CLP(FD) 0.9.2, 1.2, XLOG 6 */
X is gcd(0,3*2^100),
X =:= 3*2^100.

SWI-Prolog can also do it:

?- X is gcd(-12*2^100,-18*2^100).
X = 7605903601369376408980219232256.
?- X is gcd(0,3*2^100).
X = 3802951800684688204490109616128.

burs...@gmail.com schrieb:

j4n bur53

unread,
May 31, 2018, 5:16:28 PM5/31/18
to
but some bignum functions have different names,
i started providing:

?- X is isqrt(77*2^100).
X = 9879731586312133

In SWI-Prolog its done:

?- X is 77*2^100, nth_integer_root_and_remainder(2, X, R, _).
X = 97609096217573663915246146813952,
R = 9879731586312133

This is all CLP(FD) stuff related to the "The GNU
Multiple Precision Arithmetic Library", in case you do
not do it in Java or directly in Prolog.

j4n bur53 schrieb:

burs...@gmail.com

unread,
May 31, 2018, 5:19:50 PM5/31/18
to
Anyway I didn't wanted to disturb your sleep.
Vienna and Bern, I guess they have already
folded up the sidewalks.

Joachim Schimpf

unread,
Jun 1, 2018, 6:14:25 PM6/1/18
to
On 31/05/18 16:09, Ulrich Neumerkel wrote:
> burs...@gmail.com writes:
...
>> Here is an example how such a self declaration looks like from
>>
>> ECLiPSe Prolog, namely:
>
> This self declaration is from 2018-01. After dicussions.
>

This is a misleading statement. To clarify:

1. a corresponding "self declaration" was released together with the first
version of ECLiPSe's ISO-Prolog processor in June 2013

2. it does not owe anything to discussions with anyone

3. it is meant to satisfy section 5.4 of the standard, which reads:

A conforming Prolog processor shall be accompanied
by documentation that completes the definition of every
implementation defined and implementation specific feature
specified in this part of ISO/IEC 132 11.


Regards,
Joachim Schimpf
ECLiPSe maintainer

burs...@gmail.com

unread,
Jun 1, 2018, 6:23:32 PM6/1/18
to
I like your "self declaration", it puts life
into the ISO standard. Passages of the ISO standard

become more life, when there are examples.
Otherwise one might skip such a passage easily

and consider it some academic exercise...

Ulrich Neumerkel

unread,
Jun 2, 2018, 6:12:51 AM6/2/18
to
Joachim Schimpf <jsch...@invalid.invalid> writes:
>On 31/05/18 16:09, Ulrich Neumerkel wrote:
>> burs...@gmail.com writes:
>...
>>> Here is an example how such a self declaration looks like from
>>>
>>> ECLiPSe Prolog, namely:
>>
>> This self declaration is from 2018-01. After dicussions.
>
>This is a misleading statement. To clarify:
>
>1. a corresponding "self declaration" was released together with the first
>version of ECLiPSe's ISO-Prolog processor in June 2013

All self-declarations of ECLiPSe prior to 2018-01 were not declarations
of conformity. Most notably, http://eclipseclp.org/relnotes/rel61.html
did contain a mode "lib(iso) that was explictitly not conforming.

>2. it does not owe anything to discussions with anyone

Discussion with you on this very topic went on in the time span
2011-04..2017-08. Whether or not this influenced you, I know not.

burs...@gmail.com

unread,
Jun 5, 2018, 9:51:00 AM6/5/18
to
I am still chewing on 9^(9^9), 16 minutes is not so bad.

"To additionally output the ca. 370 million decimal digits, if
it would use 1 ms per digit, would only need 370'000 ms.
Thats a third of the time I needed to compute the exact
digits in the above, i.e. 974,318 ms, and store them in memory."

Nevertheless, somebody an idea to do it faster? Just curious:

Whats the fastest way to compute 9^(9^9)
https://math.stackexchange.com/q/2808923/4414

j4n bur53

unread,
Jun 5, 2018, 9:54:19 AM6/5/18
to
I was thinking about computing:

3^(2*(9^9))

Should give the same result as 9^(9^9). I
even don't know how to produce the digits of
3^n fast, for an arbitrary n. Is this posssible?

Or is natural number multiplication that nasty?

burs...@gmail.com schrieb:

burs...@gmail.com

unread,
Jun 5, 2018, 10:13:49 AM6/5/18
to
Now I have the feeling that there is something wrong
with my system and also with SWI-Prolog. For example
I think this error is wrong:

Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.15)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.

?- _ is 9^(9^9).
ERROR: Stack limit (1.0Gb) exceeded

I did the following simple experiment, I first defined
a predicate pow/3 as follows:

pow(_,0,1) :- !.
pow(X,1,X) :- !.
pow(X,N,Y) :-
M is N//2, pow(X,M,A),
J is N mod 2, pow(X,J,B),
Y is (A*A)*B.

And then I get for the computation neither a memory
overflow nor a very long runtime:

Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.15)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.

?- pow(9,9,X).
X = 387420489.

?- time((pow(9,9,X), pow(9,X,_))).
% 159 inferences, 7.500 CPU in 8.514 seconds (88% CPU, 21 Lips)

So two things are not ok:
- SWI-Prolog refusing to compute it for ordinary (^)/2.
- Jekejeke Prolog taking 16 minutes to compute it for ordinary (^)/2..

burs...@gmail.com

unread,
Jun 5, 2018, 10:20:20 AM6/5/18
to

burs...@gmail.com

unread,
Jun 5, 2018, 10:27:48 AM6/5/18
to
Maybe I should write the pow/3 predicate result
to a file and compare it to some other computation.

But so far, I am assuming, that produces a correct
result, and can do this in 8.5 secs.

burs...@gmail.com

unread,
Jun 5, 2018, 10:31:54 AM6/5/18
to
My opinion, the operator (^)/2 should be at least
as good as a predicate pow/3. Otherwise it doesn't

make sense to migrate code, that originally used
something like pow/3. Thats the idea of the ticket.

I don't expect Ulrich Neumerkel and the ISO core
standard saying the same...

j4n bur53

unread,
Jun 5, 2018, 10:48:47 AM6/5/18
to
Disclaimer: pow/3 is not the usual algorithm that
is implement. But its very similar. So pow/3 doesn't
do really the following:

x^y = x^(2^k1) * ... * x^(2^kn)

where k1,..,kn are the bit positions. The result
is rather something like:

x^y = (... (x^2 ...)^2 ...)^2 [* x]

Usually pow/3 is not implemented in bignum libraries
since it uses recursion, and the other iterative
algorithm is implemented.

But somehow this irrelevant to
show the potential performance.

burs...@gmail.com schrieb:

burs...@gmail.com

unread,
Jun 5, 2018, 11:03:13 AM6/5/18
to
Woa, the issue got already closed.
Cool! I just noticed the ECLiPSe Prolog can also do it:

ECLiPSe Constraint Logic Programming System [kernel threads]
Version 7.0 #36 (x86_64_nt), Sun Jan 28 10:18 2018

[eclipse 2]: _ is 9^(9^9).
Yes (20.09s cpu)

Very currious what the SWI timing will be!

burs...@gmail.com

unread,
Jun 5, 2018, 6:53:20 PM6/5/18
to
Woa, SWI-Prolog even manages to write the result on
a file. I get the following result, takes around 2 minutes:

?- open('C:\\Users\\Jan Burse\\Desktop\\ss\\bigpow999.txt', write, S), time((pow(9,9,X), pow(9,X,Y), write(S,Y), nl(S), fail; true)), close(S).
% 161 inferences, 145.125 CPU in 154.276 seconds (94% CPU, 1 Lips)
S = <stream>(000002C16CEEF480).

And the resulting file has this size:

06.06.2018 00:48 369'693'102 bigpow999.txt

I tried the same with ECLiPSe Prolog, but it simply
crashes. I tried this in ECLiPSe Prolog, but it didn't
work:

[eclipse 1]: open('C:\\Users\\Jan Burse\\Desktop\\ss\\bigpow999e.txt', write, S), (Y is 9^(9^9), write(S,Y), nl(S), fail; true), close(S).

burs...@gmail.com

unread,
Jun 6, 2018, 5:00:19 AM6/6/18
to
Ha Ha, pow/3 is faster than (^)/2 in Java:

Java, the (A*A)*B step measured:

% Up 1,059 ms, GC 14 ms, Thread Cpu 1,031 ms (Current 06/06/18 10:07:54)
% Up 2,320 ms, GC 11 ms, Thread Cpu 2,297 ms (Current 06/06/18 10:07:56)
% Up 5,852 ms, GC 27 ms, Thread Cpu 5,812 ms (Current 06/06/18 10:08:02)
% Up 15,949 ms, GC 179 ms, Thread Cpu 15,782 ms (Current 06/06/18 10:08:18)
% Up 45,419 ms, GC 540 ms, Thread Cpu 44,796 ms (Current 06/06/18 10:09:03)
% Up 116,740 ms, GC 1,234 ms, Thread Cpu 115,235 ms (Current 06/06/18 10:11:00)
% Up 326,318 ms, GC 2,266 ms, Thread Cpu 323,765 ms (Current 06/06/18 10:16:26)

Looks like a total that is half of the 974,318 ms I once measured here:
https://math.stackexchange.com/q/2808923/4414

GNU, the (A*A)*B step measured.

% 2 inferences, 0.047 CPU in 0.047 seconds (100% CPU, 43 Lips)
% 2 inferences, 0.094 CPU in 0.109 seconds (86% CPU, 21 Lips)
% 2 inferences, 0.203 CPU in 0.219 seconds (93% CPU, 10 Lips)
% 2 inferences, 0.438 CPU in 0.484 seconds (90% CPU, 5 Lips)
% 2 inferences, 0.875 CPU in 0.984 seconds (89% CPU, 2 Lips)
% 2 inferences, 1.828 CPU in 2.062 seconds (89% CPU, 1 Lips)
% 2 inferences, 3.859 CPU in 4.202 seconds (92% CPU, 1 Lips)

Ulrich Neumerkel

unread,
Jun 6, 2018, 10:22:35 AM6/6/18
to
burs...@gmail.com writes:
>My opinion, the operator (^)/2 should be at least
>as good as a predicate pow/3. Otherwise it doesn't
>make sense to migrate code, that originally used
>something like pow/3. Thats the idea of the ticket.
>
>I don't expect Ulrich Neumerkel and the ISO core
>standard saying the same...

Nice! I never thought that 9^9^9 still could be calculated.
My favorite number I use for such tests is 7^7^7.

burs...@gmail.com

unread,
Jun 6, 2018, 10:27:28 AM6/6/18
to
Seems to be a new result. Not archivable in Java
at the moment, with the standard BigInteger.

Has possibly to do with FFT multiplication, see
also this table here:

https://gmplib.org/manual/Multiplication-Algorithms.html#Multiplication-Algorithms

Cant say for sure whats going on.

burs...@gmail.com

unread,
Jun 6, 2018, 1:35:14 PM6/6/18
to
Maybe I should just wait for JDK 9. But JDK 9, last
time I tested has an awful GC. But this looks interesting;

"This code has been merged into OpenJDK 8 except
for the Schönhage-Strassen and Barrett algorithms
which are planned for OpenJDK 9."
https://github.com/tbuktu/bigint

Oki Doki

burs...@gmail.com

unread,
Jul 7, 2018, 10:50:36 AM7/7/18
to
Now I have a nice benchmark example, that shows that
bisection is too slow for isqrt. Newton is already
better, but not what GMP provides:

In SWI-Prolog this example is very fast:

?- X is 10^1000000 - 3^2095903,
time((nth_integer_root_and_remainder(2, X, _, _))), fail; true.
% 2 inferences, 0.016 CPU in 0.016 seconds (100% CPU, 128 Lips)
true.

Bisection hangs. But I already managed newton to give:

?- X is 10^1000000 - 3^2095903,
time((newton(X,_))), fail; true.
% Up 3,997 ms, GC 99 ms, Thread Cpu 3,954 ms (Current 07/07/18 15:16:01)
Yes

Does ECLiPSe Prolog have isqrt/1 somewhere? This one
doesn't work:

[eclipse 3]: lib(gfd).

[eclipse 4]: X is isqrt(100).
calling an undefined procedure isqrt(100, X) in module eclipse
Abort

Credits:
Example taken from here, which shows the aforementioned
example similar performance for python3:

n = mpz(10**1000000 - 3**2095903)

...

$ python3 benchmark.py
0.01685619354248047

https://mathematica.stackexchange.com/q/165041/5243

Am Donnerstag, 31. Mai 2018 23:16:28 UTC+2 schrieb burs...@gmail.com:
0 new messages