Rounding still not fixed in Scryer Prolog. Look
what a nice test case I am using:
?- atom_integer(X, 2, 166153499473114502559719956244594689).
X = '1000000000000000000000000000000000000000 000000000000010000000000000000000000000000000 000000000000000000000000000000001'.
And whats the result:
$ target/release/scryer-prolog -v
"v0.9.1-151-g17450520"
$ target/release/scryer-prolog
?- X is float(166153499473114502559719956244594689).
X = 1.661534994731145e35.
?- Y = 1.6615349947311452e+35.
Y = 1.6615349947311452e35.
?- X is float(166153499473114502559719956244594689)-1.6615349947311452e+35.
X = -3.6893488147419103e19.
?-
Its not correctly rounded!
Yeah today I created a ticket in GitHub issues.
Now I need to take a SPA nap:
Cute Kitten Really Enjoys SPA
https://www.youtube.com/watch?v=L7lVrWY9zQE
P.S.: No wonder Scryer Prolog has 242 tickets: https://github.com/mthom/scryer-prolog/issues
Mostowski Collapse schrieb:
Rounding still not fixed in Scryer Prolog. Look
what a nice test case I am using:
?- atom_integer(X, 2, 166153499473114502559719956244594689).
X = '1000000000000000000000000000000000000000
000000000000010000000000000000000000000000000
000000000000000000000000000000001'.
And whats the result:
$ target/release/scryer-prolog -v
"v0.9.1-151-g17450520"
$ target/release/scryer-prolog
?- X is float(166153499473114502559719956244594689).
X = 1.661534994731145e35.
?- Y = 1.6615349947311452e+35.
Y = 1.6615349947311452e35.
?- X is
float(166153499473114502559719956244594689)-1.6615349947311452e+35.
X = -3.6893488147419103e19.
?-
Its not correctly rounded!
We hope that a collection of PIPs willincrease the visibility of Prolog and its growth. https://prolog-lang.pages.software.imdea.org/implementors-forum/FAQ.html
Hi,
How did the basilisk lived so long at the chamber of
secrets? I always just figured they were excellent at
hibernating and only awoke once called for.
How it started:
We hope that a collection of PIPs willincrease the visibility of Prolog and its growth. https://prolog-lang.pages.software.imdea.org/implementors-forum/FAQ.html
How its going:
11:00-11:15 Proposal: Binary prefix operators. Presenter: François Fages 11:15-11:30 Proposal: CSV interface. Presenter: Daniel Jurjo https://prolog-lang.org/ImplementersForum/PIPWorkshop2024.html
These talks will possibly be published in some
Spinger Journal behind a paywall right?
Nobody has seen these PIPs elsewhere so far.
Bye
Hi,
Interestingly in the old times, Prolog dicts that
are functional datastructures were called
multiple version hash tables (MVIIT):
Hash Tables in Logic Programming
The paper gives informal semantics for hash tables
as partial functions on logical terms for Prolog's
Horn clause language, and the implementation has been
used in Tricia, an implementation of Prolog
developed at Uppsala University.
Jonas Barklund and Hakan Millroth,
International Conference on Logic Programming 1987, https://www2.it.uu.se/research/csd/reports/0040.pdf
Oki Doki
Bye
Mild Shock schrieb:
Hi,
How did the basilisk lived so long at the chamber of
secrets? I always just figured they were excellent at
hibernating and only awoke once called for.
How it started:
We hope that a collection of PIPs willincrease the visibility of Prolog and its growth.
https://prolog-lang.pages.software.imdea.org/implementors-forum/FAQ.html
How its going:
11:00-11:15 Proposal: Binary prefix operators. Presenter: François Fages
11:15-11:30 Proposal: CSV interface. Presenter: Daniel Jurjo
https://prolog-lang.org/ImplementersForum/PIPWorkshop2024.html
These talks will possibly be published in some
Spinger Journal behind a paywall right?
Nobody has seen these PIPs elsewhere so far.
Bye
I came up with a findall/3 for SWI-Prolog that
doesn’t use call_cleanup/2. The findall2/3 realization
uses nb_linkarg/3 and duplicate_term/2.
findall2(Template, Goal, List) :-
sys_find2_init(State),
(Goal, sys_find2_next(Template, State), fail; true),
sys_find2_fini(State, List).
sys_find2_init(X) :-
X = v(_,_),
C = [-|_],
nb_linkarg(1, X, C),
nb_linkarg(2, X, C).
sys_find2_next(T, X) :-
C = [_|_],
duplicate_term(T, H),
nb_linkarg(1, C, H),
arg(1, X, J), %%% known end cell
nb_linkarg(2, J, C),
nb_linkarg(1, X, C).
sys_find2_fini(v(C,D), L) :-
nb_linkarg(2, C, []),
arg(2, D, L).
Its not as fast as the bundled findall/3.
I can speed it up, if I use nb_setarg/3 instead
of the explicit duplicate_term/2 and nb_linkarg/3 combo.
The change is as follows:
/* Before */
sys_find2_next(T, X) :-
C = [_|_],
duplicate_term(T, H),
nb_linkarg(1, C, H),
arg(1, X, J),
nb_linkarg(2, J, C),
nb_linkarg(1, X, C)
/* After */
sys_find2_next(T, X) :-
C = [_|_],
nb_setarg(1, C, T),
arg(1, X, J),
nb_linkarg(2, J, C),
nb_linkarg(1, X, C).
Now the timings are better:
/* Before */
?- time(test2).
% 6,007,999 inferences, 0.422 CPU in 0.427
seconds (99% CPU, 14241183 Lips)
true.
/* After */
?- time(test2).
% 5,007,999 inferences, 0.297 CPU in 0.298
seconds (100% CPU, 16869049 Lips)
true.
A wooping more than 100 milliseconds are gone!
It all began with the bagof/3 choker:
test :-
bagof(X, N^(between(1,300,X), between(1,300,N),
length(_,N)), _), fail; true.
Which makes Prolog system tumble:
/* SWI-Prolog 9.3.14 */
?- time(test).
Action (h for help) ? abort
% 468,739 inferences, 52.016 CPU in 53.069 seconds (98% CPU, 9012 Lips) Execution Aborted
/* Scryer Prolog 0.9.4-201 */
?- time(test).
^C % CPU time: 110.153s, 145_508_466 inferences
error('$interrupt_thrown',repl/0).
Its mostlikely the same old problem that was
observed years ago, in that the canonicalization
of variables before the keysort/2 creates long
instantiation chains. It can be solved by adjusting
the unification order. Here is a take in Dogelog Player:
/* Dogelog Player 1.2.5 */
?- time(test).
% Zeit 7405 ms, GC 21 ms, Lips 3962971, Uhr 10.11.2024 00:57
true.
But we can also do without term_variables/3 or
term_variable/2. don’ have tries in my system.
But I recently introduced Okasaki tree, but it
turned out that they are totally useless. What
works better in my case was hash+keysort, as
strange as it may sound.
I believe it depends on the grouping factor.
If there is a high grouping factor there is
higher precentage of read from the grouping
datastructure and than write into the
grouping datastructure. So if read is only O(1)
as in hash, you have better preformance than if
read is O(log N) as in tree. And you can also
afford a later keysort. Here is the bagof/3 choker
with hash+keysort compared to tree:
/* Dogelog Player 1.2.5, tree */
?- time(test3).
% Zeit 6073 ms, GC 1 ms, Lips 5182931, Uhr 10.11.2024 00:58
true.
/* Dogelog Player 1.2.5, hash+keysort */
?- time(test4).
% Zeit 3070 ms, GC 2 ms, Lips 9808736, Uhr 10.11.2024 00:58
true.
Quite amazing, if we compare to the traditional bagof/3:
/* Trealla Prolog 2.59.17, keysort */
?- time(test).
% Time elapsed 13.280s, 16158649 Inferences, 1.217 MLips
true.
Mild Shock schrieb:
It all began with the bagof/3 choker:
test :-
bagof(X, N^(between(1,300,X), between(1,300,N),
length(_,N)), _), fail; true.
Which makes Prolog system tumble:
/* SWI-Prolog 9.3.14 */
?- time(test).
Action (h for help) ? abort
% 468,739 inferences, 52.016 CPU in 53.069 seconds (98% CPU, 9012 Lips)
Execution Aborted
/* Scryer Prolog 0.9.4-201 */
?- time(test).
^C % CPU time: 110.153s, 145_508_466 inferences
error('$interrupt_thrown',repl/0).
Its mostlikely the same old problem that was
observed years ago, in that the canonicalization
of variables before the keysort/2 creates long
instantiation chains. It can be solved by adjusting
the unification order. Here is a take in Dogelog Player:
/* Dogelog Player 1.2.5 */
?- time(test).
% Zeit 7405 ms, GC 21 ms, Lips 3962971, Uhr 10.11.2024 00:57
true.
Concerning the input (xxx yyy zzz) the OP wrote:
I would expect it to print zzz(xxx(yyy)).
Where did he get this requirement from, he didn’t
compare other Prolog systems, right? So it came from
his applicationdomain. But what was his application
domain? Ok, lets proceed to an example with multiple
brakets. Lets make the Pascal “begin” “end” example,
by replacing xxx and zzz by “begin” and “end”.
I get this result:
?- member(X,[begin,end]), current_op(Y,Z,X).
X = (begin), Y = 1100, Z = fy ;
X = (end), Y = 1100, Z = yf.
?- X = (begin
| x = 1;
| y = 2;
| begin
| z = 3
| end
| end).
X = (begin x=1;y=2;begin z=3 end end).
But is the abstract parse term, the Prolog result useful?
Here is the SWI-Prolog and the SICStus
Prolog abstract parse term. This is the real
nightmare of every computer science professor,
who wants to use Prolog in a compiler
construction course:
/* SWI-Prolog 9.3.14 */
end(end(begin(;(=(x,1),;(=(y,2),begin(=(z,3)))))))
/* SICStus Prolog 4.9.0 */
begin(;(=(x,1),;(=(y,2),begin(end(end(=(z,3)))))))
On the other hand mostlikely the OP @horsh
would expect:
/* What the End-User wants */ end(begin(;(=(x,1),;(=(y,2),end(begin(=(z,3)))))))
I think its impossible to do in any Prolog system,
you would need a programming language with the
possibility to do mixfix syntax definitions,
like for example in Isabelle/HOL:
(* Define the mixfix syntax for a Pascal-like block *)
syntax
"_begin_end" :: "'a ⇒ 'a" ("begin _ end")
Or otherwise use DCG to write your own parser
for the DSL at hand, that you want to parse.
Since Prolog operators cannot model mixfix syntax,
at least SWI-Prolog and SICStus Prolog fail,
and I guess other Prolog systems fail as well.
Mild Shock schrieb:
Concerning the input (xxx yyy zzz) the OP wrote:
I would expect it to print zzz(xxx(yyy)).
Where did he get this requirement from, he didn’t
compare other Prolog systems, right? So it came from
his applicationdomain. But what was his application
domain? Ok, lets proceed to an example with multiple
brakets. Lets make the Pascal “begin” “end” example,
by replacing xxx and zzz by “begin” and “end”.
I get this result:
?- member(X,[begin,end]), current_op(Y,Z,X).
X = (begin), Y = 1100, Z = fy ;
X = (end), Y = 1100, Z = yf.
?- X = (begin
| x = 1;
| y = 2;
| begin
| z = 3
| end
| end).
X = (begin x=1;y=2;begin z=3 end end).
But is the abstract parse term, the Prolog result useful?
Lets cut through the thicket. There is no
real world use case of a (fy 1 yf). Take again
the Pascal “begin” “end” mixfix example.
Typically we want to then go on and write
for example a compiler:
:- op(1100,fy,begin).
:- op(1100,yf,end).
compile((begin X end)) --> compile(X). %%% scoping omitted
compile((X;Y)) --> compile(X), compile(Y).
compile((V=E)) --> [load(E),store(V)].
The problem is the pattern (begin X end) will
not work, if multiple (begin … end) are involved
in the compile/1 call. You can try yourself, no
Prolog system can do it:
/* SWI-Prolog */
?- X = (begin
x = 1;
begin
y = 2
end
end), compile(X, L, []).
false.
%%% expected L = [load(1),store(x),load(2),store(y)]
/* SICStus Prolog */
?- X = (begin
x = 1;
begin
y = 2
end
end), compile(X, L, []).
no.
%%% expected L = [load(1),store(x),load(2),store(y)]
The reason is that the parser will join multiple yf,
similarly it would join multiple fy. The parser will
not follow a braket pattern. At least I don’t know
any Prolog system that can do it.
Mild Shock schrieb:
Here is the SWI-Prolog and the SICStus
Prolog abstract parse term. This is the real
nightmare of every computer science professor,
who wants to use Prolog in a compiler
construction course:
/* SWI-Prolog 9.3.14 */
end(end(begin(;(=(x,1),;(=(y,2),begin(=(z,3)))))))
/* SICStus Prolog 4.9.0 */
begin(;(=(x,1),;(=(y,2),begin(end(end(=(z,3)))))))
On the other hand mostlikely the OP @horsh
would expect:
/* What the End-User wants */
end(begin(;(=(x,1),;(=(y,2),end(begin(=(z,3)))))))
I think its impossible to do in any Prolog system,
you would need a programming language with the
possibility to do mixfix syntax definitions,
like for example in Isabelle/HOL:
(* Define the mixfix syntax for a Pascal-like block *)
syntax
"_begin_end" :: "'a ⇒ 'a" ("begin _ end")
Or otherwise use DCG to write your own parser
for the DSL at hand, that you want to parse.
Since Prolog operators cannot model mixfix syntax,
at least SWI-Prolog and SICStus Prolog fail,
and I guess other Prolog systems fail as well.
Mild Shock schrieb:
Concerning the input (xxx yyy zzz) the OP wrote:
I would expect it to print zzz(xxx(yyy)).
Where did he get this requirement from, he didn’t
compare other Prolog systems, right? So it came from
his applicationdomain. But what was his application
domain? Ok, lets proceed to an example with multiple
brakets. Lets make the Pascal “begin” “end” example,
by replacing xxx and zzz by “begin” and “end”.
I get this result:
?- member(X,[begin,end]), current_op(Y,Z,X).
X = (begin), Y = 1100, Z = fy ;
X = (end), Y = 1100, Z = yf.
?- X = (begin
| x = 1;
| y = 2;
| begin
| z = 3
| end
| end).
X = (begin x=1;y=2;begin z=3 end end).
But is the abstract parse term, the Prolog result useful?
Typically we want to then go on and write<snip>
for example a compiler:
:- op(1100,fy,begin).
:- op(1100,yf,end).
compile((begin X end)) --> compile(X). %%% scoping omitted
compile((X;Y)) --> compile(X), compile(Y).
compile((V=E)) --> [load(E),store(V)].
The problem is the pattern (begin X end) will
not work, if multiple (begin … end) are involved
in the compile/1 call. You can try yourself, no
Prolog system can do it:
/* SWI-Prolog */
?- X = (begin
x = 1;
begin
y = 2
end
end), compile(X, L, []).
false.
%%% expected L = [load(1),store(x),load(2),store(y)]
This seems to do the trick:
```
% SWI-Prolog 9.2.7
:- op(1100, fy, begin).
:- op(1100, yf, end).
compile((begin XEnd)) --> compile(XEnd).
compile((X end)) --> compile(X).
compile((X;Y)) --> compile(X), compile(Y).
compile((V=E)) --> [load(E),store(V)].
compile_t(X, L) :-
X = (
begin
x = 1;
begin
y = 2
end
end
),
compile(X, L, []).
```
```
?- compile_t(X, L).
X = (begin x=1;begin y=2 end end),
L = [load(1),store(x),load(2),store(y)].
```
-Julio
Yes, maybe, it depends. You would
need to fill in some logic for the
block functionality, like opening
and closing a table with variable
names. And try it as such with a larger
variety of example. Also compare whether
it works for both SWI-Prolog and SICStus
Prolog. What one can already see for sure,
the compile is not extremly safe anymore.
It would also accept non well formed
input. Like you can call it with unbalanced
begin end now, and the compile/1 clause
pattern matching will not fail, and it
will start producing some code:
?- compile((begin x=1 end end)).
But maybe this is a minor problem. Another
challenge is for example the Pascal if-then-else.
Basically a mixfix with 3 holes.
if _ then _ else _
https://www.tutorialspoint.com/pascal/pascal_if_then_else_statement.htm
Just like in the begin end case, where
we can provide non-well formed input
like (begin x=1 end end). Ordinary
Prolog operators will again not provide
the safety and versatility for writing rules.
Julio Di Egidio schrieb:
This seems to do the trick:
```
% SWI-Prolog 9.2.7
:- op(1100, fy, begin).
:- op(1100, yf, end).
compile((begin XEnd)) --> compile(XEnd).
compile((X end)) --> compile(X).
compile((X;Y)) --> compile(X), compile(Y).
compile((V=E)) --> [load(E),store(V)].
compile_t(X, L) :-
X = (
begin
x = 1;
begin
y = 2
end
end
),
compile(X, L, []).
```
```
?- compile_t(X, L).
X = (begin x=1;begin y=2 end end),
L = [load(1),store(x),load(2),store(y)].
```
-Julio
Concerning the input (xxx yyy zzz) the OP wrote:
I would expect it to print zzz(xxx(yyy)).
Where did he get this requirement from, he didn’t
compare other Prolog systems, right? So it came from
his applicationdomain. But what was his application
domain? Ok, lets proceed to an example with multiple
brakets. Lets make the Pascal “begin” “end” example,
by replacing xxx and zzz by “begin” and “end”.
I get this result:
?- member(X,[begin,end]), current_op(Y,Z,X).
X = (begin), Y = 1100, Z = fy ;
X = (end), Y = 1100, Z = yf.
?- X = (begin
| x = 1;
| y = 2;
| begin
| z = 3
| end
| end).
X = (begin x=1;y=2;begin z=3 end end).
But is the abstract parse term, the Prolog result useful?
Yes, maybe, it depends. You would
need to fill in some logic for the
block functionality, like opening
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 997 |
Nodes: | 10 (0 / 10) |
Uptime: | 227:13:47 |
Calls: | 13,046 |
Calls today: | 1 |
Files: | 186,574 |
Messages: | 3,292,818 |