didoudiaz / gprolog Goto Github PK
View Code? Open in Web Editor NEWGNU Prolog
License: Other
GNU Prolog
License: Other
$ ./bin/gprolog
GNU Prolog 1.6.0 (64 bits)
Compiled Jun 27 2023, 16:35:39 with gcc
Copyright (C) 1999-2023 Daniel Diaz
| ?- current_prolog_flag(max_integer, V), W is V + 1.
V = 1152921504606846975
W = -1152921504606846976
yes
| ?-
Compiled multifile predicates are called indefinitely (at least under some conditions) when examined under the debugger. I assume this has something to do with how the debugger handles auxillary clauses of multifile predicates, but the code involved isn't completely clear to me. This affects HEAD (as shown) as well as the OpenBSD packaged version I have installed (1.4.5).
The error does not occur when the shown bugtest.pl
file is consulted/loaded.
sotto-voce$ uname -a
OpenBSD sotto-voce 7.0 GENERIC.MP#227 amd64
sotto-voce$ (cd ~/fsrc/gprolog && git describe)
v1.5.0-1-g8a8220dc
sotto-voce$ cat bugtest.pl
:- multifile(p/0).
p.
sotto-voce$ ~/fsrc/gprolog/src/TopComp/gplc bugtest.pl
sotto-voce$ ./bugtest
GNU Prolog 1.5.0 (64 bits)
Compiled Sep 24 2021, 10:34:40 with cc
Copyright (C) 1999-2021 Daniel Diaz
| ?- debug, p.
The debugger will first leap -- showing spypoints (debug)
Fatal Error: local stack overflow (size: 16384 Kb, reached: 16384 Kb, environment variable used: LOCALSZ)
Under trace:
| ?- trace, p.
The debugger will first creep -- showing everything (trace)
1 1 Call: p ?
2 2 Call: p ?
3 3 Call: p ?
4 4 Call: p ? g
Ancestors:
1 1 p
2 2 p
3 3 p
4 4 Call: p ? A
Alternatives:
1 1 p
2 2 p
3 3 p
4 4 p
--------------
4 4 Call: p ? W
Welcome to the WAM debugger - experts only
(wam debug) backtrack all
local[367]: $debug_exec_cmd/6
local[352]: repeat/0
local[331]: $debug_port1/6
local[303]: $catch_internal1/5
local[276]: $debug_call1/8
local[250]: $catch_internal1/5
local[223]: $debug_call1/8
local[197]: $catch_internal1/5
local[170]: $debug_call1/8
local[144]: $catch_internal1/5
local[117]: $debug_call1/8
local[87]: $$top_level2/0_$aux4/3
local[66]: repeat/0
local[40]: $catch_internal1/5
local[26]: repeat/0
Latest versions of LVM and Trealla Prolog implement a function_property/2
built-in predicate, which provides similar functionality to the de facto standard predicate_property/2
built-in predicate, allowing checking or enumerating the properties of a given arithmetic function. The function_property/2
predicate allows clean checking if an arithmetic function is defined, simplifying e.g. portability linter checks for arithmetic expressions. The first argument is a function template (e.g. abs(_)
) and the second argument is the property. Four properties are specified:
built_in
(function is a defined built-in arithmetic function)foreign
(function is a defined arithmetic function implemented using the FLI)static
(function is a static arithmetic function)dynamic
(function is a dynamic arithmetic function)The dynamic
is meant for Prolog systems that allow runtime definition of new arithmetic functions (e.g. LVM). Built-in and foreign functions usually also have the static
property.
The predicate spec is:
Template:
function_property(Function, Property)
Modes and number of proofs:
function_property(+callable, ?function_property)
- zero_or_more
Exceptions:
Function
is a variable:instantiation_error
Function
is neither a variable nor a callable term:type_error(callable, Function)
Property
is neither a variable nor an atom:type_error(atom, Property)
Property
is an atom but not a valid function property:domain_error(function_property, Property)
Examples:
Check that popcount/1
is a built-in arithmetic function:
?- function_property(popcount(_), built_in).
true.
Would it be possible to add this predicate to GNU Prolog?
| ?- length(L,N), N > 8, ( permutation(L,_), false ; true).
L = [_,_,_,_,_,_,_,_,_]
N = 9 ? a
L = [_,_,_,_,_,_,_,_,_,_]
% no immediate display of N = 10
So I am looking at a sequence of answers that take quite some time to compute. I enter a
to see all of them, but then the next answer is only shown incompletely, the line N = 10 will only be shown when the next answer will be ready.
(I tried to celebrate the safe, conforming implementation of integers, but meanwhile ran against memory limits)
| ?- length(_,I),N is 2^2^I, catch(length(L,N),Err,true).
I = 0
L = [_, _]
N = 2 ? ;
I = 1
L = [_, _, _, _]
N = 4 ? ;
I = 2
L = [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]
N = 16 ? ;
I = 3
L = [_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _]
N = 256 ? ;
I = 4
L = _ % omitted
N = 65536 ? ;
Fatal Error: global stack overflow (size: 100000 Kb, reached: 99997 Kb, environment variable used: GLOBALSZ)
Expected:
I = 5
N = 4294967296
Err = error(resource_error(...),...)
The error handling mechanism is designed to catch such errors as well. Strictly speaking, an implementation does not have to handle such cases, but it does help a lot.
With 7adebe2 from the src
directory:
$ CC=/opt/local/bin/gcc-mp-12 ./configure && make && sudo make install
...
./mkinstalldirs /usr/local/gprolog-1.6.0 /usr/local/gprolog-1.6.0/bin \
/usr/local/gprolog-1.6.0/include /usr/local/gprolog-1.6.0/lib
for i in README COPYING VERSION NEWS ChangeLog gprolog.ico; do /opt/local/bin/ginstall -c -m 644 ../$i /usr/local/gprolog-1.6.0; done
for i in gplc hexgplc gprolog pl2wam wam2ma ma2asm fd2c; do /opt/local/bin/ginstall -c */$i /usr/local/gprolog-1.6.0/bin; done
for i in top_level_main.o top_level.o all_pl_bips.o debugger.o all_fd_bips.o; do /opt/local/bin/ginstall -c -m 644 */$i /usr/local/gprolog-1.6.0/lib; done
for i in libengine_pl.a libbips_pl.a liblinedit.a libengine_fd.a libbips_fd.a; do /opt/local/bin/ginstall -c -m 644 */$i /usr/local/gprolog-1.6.0/lib; done
for i in gprolog.h fd_to_c.h; do EnginePl/cpp_headers $i ./$i EnginePl EngineFD BipsPl BipsFD; /opt/local/bin/ginstall -c -m 644 ./$i /usr/local/gprolog-1.6.0/include; rm -f $i; done
/bin/sh: EnginePl/cpp_headers: No such file or directory
ginstall: cannot stat './gprolog.h': No such file or directory
/bin/sh: EnginePl/cpp_headers: No such file or directory
ginstall: cannot stat './fd_to_c.h': No such file or directory
...
In the manual, the documentation of the last_read_start_line_column/2
predicate reads:
... with the line number and the column number associated with the start of the last read predicate.
I think you mean: "... the last read term."
Running the Logtalk test set for conditional compilation directives (git version) shows a failed test:
$ logtalk_tester -p gnu
% Batch testing started @ 2023-06-07 19:29:58
% Logtalk version: 3.67.0-b01
% GNU Prolog version: 1.6.0
%
% Documents/Logtalk/logtalk3/tests/prolog/directives/conditional_compilation
% 39 tests: 0 skipped, 38 passed, 1 failed (0 flaky)
% completed tests from object tests in 3 seconds
% clause coverage n/a
%
% Compilation errors/warnings and failed unit tests
% (compilation errors/warnings might be expected depending on the test)
! conditional_compilation_f22: failure (in 0.0 seconds)
! test goal succeeded but should have failed
! in file Documents/Logtalk/logtalk3/tests/prolog/directives/conditional_compilation/tests.lgt between lines 123-124
%
% Failed tests
Documents/Logtalk/logtalk3/tests/prolog/directives/conditional_compilation/tests.lgt - conditional_compilation_f22 @ tests
%
% 1 test sets: 1 completed, 0 skipped, 0 broken, 0 timedout, 0 crashed
% 39 tests: 0 skipped, 38 passed, 1 failed (0 flaky)
%
% Batch testing ended @ 2023-06-07 19:30:02
A simplified test file that exposes the same bug is:
:- if(fail).
f20.
:- elif(fail).
f21.
:- if(true).
f22.
:- elif(true).
f23.
:- else.
f24.
:- endif.
:- elif(fail).
f25.
:- else.
s7.
:- endif.
After loading it:
$ gprolog
GNU Prolog 1.6.0 (64 bits)
Compiled Jun 7 2023, 16:40:18 with /opt/local/bin/gcc-mp-12
Copyright (C) 1999-2023 Daniel Diaz
| ?- [ccbug].
compiling /Users/pmoura/ccbug.pl for byte code...
/Users/pmoura/ccbug.pl compiled, 16 lines read - 272 bytes written, 3 ms
yes
| ?- f22.
yes
Only the call to s7
should succeed; Calling any of the fXX
predicates should throw an existence error.
I encountered problems in the build (last issue) since I couldn't make install
out-of-the-box. I tried the --without-doc-dir but there's actually no flag in the src/configure.in
to support the following --without
prefix for the following flags:
--without-links-dir
--without-doc-dir
--without-html-dir
--without-examples-dir
If I'm going to be working on a docker-wasm output, it would be nice for these flags to work.
I'll build locally with the required packages at the moment, but will have to eventually update the src/configure.in
to support the --without
flags to support a leaner build.
I'm adding experimental support to the Logtalk help
tool to browse and search inline at the top-level interpreter the Texinfo versions of the Handbook and APIs documentation. This functionality requires connecting the Prolog standard streams to the created info
process streams. is this possible with GNU Prolog? I tried the existing exec/4-5
built-in predicates without success. You can see in the link above how I'm doing it for other Prolog systems. It would be nice to have this functionality also working with GNU Prolog.
With this fork, I am adapting wordnet-prolog for better ISO conformance. As detailed here gprolog runs the [wn_valid]
check on the database, but slowly.
A technique based on term_expansion/2
, suggested by Markus Triska, helped Scryer Prolog to better index a crucial predicate, to overcome a similar run-time and perform on par with SWI on this goal. Is there example code I might follow, to see how "to call expand_term/2
explicitly" in order to achieve the same success with gprolog?
With min
:
| ?- W is min(2^59, 2^59).
W = 576460752303423488
yes
| ?- W is min(1+2^59, 2^59).
W = 576460752303423489 % unexpected
yes
| ?-
And power:
| ?- W is (-1)^(1+2^52).
W = -1
yes
| ?- W is (-1)^(1+2^53).
W = 1 % unexpected
yes
| ?-
This was #95.
| ?- X #>= 0, length(_,X).
uncaught exception: error(type_error(integer,_#2097954(0..268435455)),(#>=)/2)
| ?- length(_,X), X #>= 0, length(_,X).
X = 0 ? ;
X = 1 ? ;
X = 2 ? ;
X = 3 ? ;
X = 4 ?
All instances permitted by _#2097954(0..268435455)
are valid integers. Therefore, a type error integer does not fit.
$ ./src/TopComp/gprolog
GNU Prolog 1.5.0 (64 bits)
Compiled Sep 16 2021, 17:45:37 with gcc
Copyright (C) 1999-2021 Daniel Diaz
| ?- length(L,2).
L = [_,_]
yes
| ?- length(L,2). % comment
L = [_,_]
yes
| ?- length(L,N). % comment
L = []
N = 0 ?
Action (; for next solution, a for all solutions, RET to stop) ?;
L = [_]
N = 1 ?
Action (; for next solution, a for all solutions, RET to stop) ?
Action (; for next solution, a for all solutions, RET to stop) ?
Action (; for next solution, a for all solutions, RET to stop) ?
Action (; for next solution, a for all solutions, RET to stop) ?
Action (; for next solution, a for all solutions, RET to stop) ?
Action (; for next solution, a for all solutions, RET to stop) ?
Action (; for next solution, a for all solutions, RET to stop) ?
yes
| ?-
I saw you added ARM support and thought it would be cool if gprolog could run on the Termux platform (maybe this is a low-hanging fruit). So I attempted to build it to see what falls out.
Errors: (copied from below)
engine1.c:137:9: error: invalid symbol kind for ADRP relocation
asm("adrp x20, _pl_reg_bank@GOTPAGE");
^
:1:2: note: instantiated into assembly here
adrp x20, _pl_reg_bank@GOTPAGE
^
engine1.c:138:9: error: invalid fixup for 64-bit load/store instruction
asm("ldr x20, [x20, _pl_reg_bank@GOTPAGEOFF]");
^
:1:2: note: instantiated into assembly here
ldr x20, [x20, _pl_reg_bank@GOTPAGEOFF]
^
I am building on an android 11 device using termux version 0.112
$ ./configure
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for gcc option to accept ISO C99... none needed
checking for gcc option to accept ISO Standard C... (cached) none needed
checking build system type... aarch64-unknown-linux-gnu
checking host system type... aarch64-unknown-linux-gnu
checking for as... as
checking for ranlib... ranlib
checking for windres... no
checking for ar... ar
checking for strip... strip
checking whether make sets $(MAKE)... yes
checking for a BSD-compatible install... /data/data/com.termux/files/usr/bin/install -c
checking whether ln -s works... yes
checking how to run the C preprocessor... gcc -E
checking for grep that handles long lines and -e... /data/data/com.termux/files/usr/bin/grep
checking for egrep... /data/data/com.termux/files/usr/bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking whether byte ordering is bigendian... no
checking for inline... inline
checking size of int... 4
checking size of long... 8
checking size of void*... 8
checking sys/ioctl_compat.h usability... no
checking sys/ioctl_compat.h presence... no
checking for sys/ioctl_compat.h... no
checking sys/siginfo.h usability... no
checking sys/siginfo.h presence... no
checking for sys/siginfo.h... no
checking termios.h usability... yes
checking termios.h presence... yes
checking for termios.h... yes
checking malloc.h usability... yes
checking malloc.h presence... yes
checking for malloc.h... yes
checking endian.h usability... yes
checking endian.h presence... yes
checking for endian.h... yes
checking sys/endian.h usability... yes
checking sys/endian.h presence... yes
checking for sys/endian.h... yes
checking byteswap.h usability... yes
checking byteswap.h presence... yes
checking for byteswap.h... yes
checking float.h usability... yes
checking float.h presence... yes
checking for float.h... yes
checking for stdlib.h... (cached) yes
checking for unistd.h... (cached) yes
checking for sys/param.h... yes
checking for getpagesize... yes
checking for working mmap... yes
checking for getpagesize... (cached) yes
checking for mprotect... yes
checking for sigaction... yes
checking for mallopt... yes
checking for fgetc... yes
checking whether htole32 is declared... yes
checking whether bswap_32 is declared... yes
checking for fpclass... no
checking for _fpclass... no
checking for isnan... yes
checking for isinf... yes
checking for atanh... yes
checking for acosh... yes
checking for asinh... yes
checking for socklen_t... yes
checking if struct sigcontext needs asm/sigcontext.h... no
checking for sigsetjmp... yes
checking for a working sigaction... yes
checking constructors execution order... first to last
checking for socket... yes
checking for gethostbyname... yes
DIRECTORIES
--> Installation: /usr/local/gprolog-1.5.0
--> Link to binaries: /usr/local/bin
--> Documentation: /usr/local/gprolog-1.5.0/doc
--> HTML documentation: /usr/local/gprolog-1.5.0/doc/html_node
--> Examples: /usr/local/gprolog-1.5.0/examples
./configure: 6698: cannot create /tmp/version_no.tex: Directory nonexistent
mv: cannot stat '/tmp/version_no.tex': No such file or directory
./configure: 6705: cannot create /tmp/copyright.tex: Directory nonexistent
mv: cannot stat '/tmp/copyright.tex': No such file or directory
configure: creating ./config.status
config.status: creating Makefile
config.status: creating TopComp/Makefile
config.status: creating Pl2Wam/Makefile
config.status: creating Wam2Ma/Makefile
config.status: creating Ma2Asm/Makefile
config.status: creating Fd2C/Makefile
config.status: creating Linedit/Makefile
config.status: creating W32GUICons/Makefile
config.status: creating EnginePl/Makefile
config.status: creating BipsPl/Makefile
config.status: creating EngineFD/Makefile
config.status: creating BipsFD/Makefile
config.status: creating Ma2Asm/FromC/Makefile
config.status: creating Win32/Makefile
config.status: creating Win32/gp-vars-iss.txt
config.status: creating EnginePl/gp_config.h
config.status: EnginePl/gp_config.h is unchanged
$ make
cd EnginePl; make config
make[1]: Entering directory '/data/data/com.termux/files/home/Projects/gnuprolog/gprolog/src/EnginePl'
gcc -fno-strict-aliasing -fcommon -O3 -fomit-frame-pointer -Wno-char-subscripts -o pl_config pl_config.c
./pl_config
-------------------------------
--- GNU PROLOG INSTALLATION ---
-------------------------------
GNU Prolog version: 1.5.0 (Jun 5 2021)
Operating system : linux-gnu
Processor : aarch64
Size of a WAM word: 64 bits
C compiler : gcc
C flags : -O3 -fomit-frame-pointer -Wno-char-subscripts
C flags machine : -fno-strict-aliasing -fcommon
Assembler : as
Assembler flags :
Loader flags :
Loader libraries : -lm
Use line editor : Yes
Use piped consult : Yes
Use sockets : Yes
Use FD solver : Yes
Use machine regs. : Yes (0 used)
Used register(s) : none
------------------------------
(cd ../TopComp; make gplc)
make[2]: Entering directory '/data/data/com.termux/files/home/Projects/gnuprolog/gprolog/src/TopComp'
gcc -fno-strict-aliasing -fcommon -O3 -fomit-frame-pointer -Wno-char-subscripts -o gplc top_comp.c -lm
make[2]: Leaving directory '/data/data/com.termux/files/home/Projects/gnuprolog/gprolog/src/TopComp'
make[1]: Leaving directory '/data/data/com.termux/files/home/Projects/gnuprolog/gprolog/src/EnginePl'
. ./SETVARS;for i in EnginePl TopComp Wam2Ma Ma2Asm Linedit BipsPl Pl2Wam Fd2C EngineFD BipsFD;do (cd $i; make) || exit 1; done;
(cd TopComp; make top-level) || exit 1;
(cd Pl2Wam; make stage2)
make[1]: Entering directory '/data/data/com.termux/files/home/Projects/gnuprolog/gprolog/src/EnginePl'
gcc -fno-strict-aliasing -fcommon -O3 -fomit-frame-pointer -Wno-char-subscripts -o cpp_headers cpp_headers.c
gplc -c -C '-O3 -fomit-frame-pointer -Wno-char-subscripts' machine.c
gplc -c -C '-O3 -fomit-frame-pointer -Wno-char-subscripts' machine1.c
gplc -c -C '-O3 -fomit-frame-pointer -Wno-char-subscripts' stacks_sigsegv.c
gplc -c -C '-O3 -fomit-frame-pointer -Wno-char-subscripts' mem_alloc.c
gplc -c -C '-O3 -fomit-frame-pointer -Wno-char-subscripts' misc.c
gplc -c -C '-O3 -fomit-frame-pointer -Wno-char-subscripts' hash_fct.c
gplc -c -C '-O3 -fomit-frame-pointer -Wno-char-subscripts' hash.c
gplc -c -C '-O3 -fomit-frame-pointer -Wno-char-subscripts' obj_chain.c
gplc -c -C '-O3 -fomit-frame-pointer -Wno-char-subscripts' engine.c
gplc -c -o engine1.o engine1.c
engine1.c:137:9: error: invalid symbol kind for ADRP relocation
asm("adrp x20, _pl_reg_bank@GOTPAGE");
^
:1:2: note: instantiated into assembly here
adrp x20, _pl_reg_bank@GOTPAGE
^
engine1.c:138:9: error: invalid fixup for 64-bit load/store instruction
asm("ldr x20, [x20, _pl_reg_bank@GOTPAGEOFF]");
^
:1:2: note: instantiated into assembly here
ldr x20, [x20, _pl_reg_bank@GOTPAGEOFF]
^
2 errors generated.
compilation failed
make[1]: *** [Makefile:83: engine1.o] Error 1
make[1]: Leaving directory '/data/data/com.termux/files/home/Projects/gnuprolog/gprolog/src/EnginePl'
make: *** [Makefile:45: all] Error 1
The default build includes a doc-required command convert
- please advise; thanks in advance.
(cd ../doc; make all)
make[1]: Entering directory '/home/jacob/projects/gprolog/doc'
convert -scale 150x150 ../gprolog.ico[5] logo.eps
/bin/sh: 1: convert: not found
make[1]: *** [Makefile:75: logo.eps] Error 127
make[1]: Leaving directory '/home/jacob/projects/gprolog/doc'
make: *** [Makefile:54: doc] Error 2
ulrich@p0:/tmp$ export PATH=/opt/gupu/gprolog-1.6.0/bin:${PATH} ; /opt/gupu/gprolog-1.6.0/bin/gprolog --consult-file inexistant GNU Prolog 1.6.0 (64 bits) Compiled Jun 26 2023, 07:25:57 with gcc -std=gnu11 Copyright (C) 1999-2023 Daniel Diaz warning: command-line consulting file inexistant failed due to existence_error(procedure,'$consult2'/1) | ?- open(inexistant,read,S). uncaught exception: error(existence_error(source_sink,inexistant),open/3)
This error suggests that $consult2/1
is not defined when in fact, the file is not existing.
?- A is 0.77 / 10.
A = 0.076999999999999999
yes
?- A is 0.78 / 10.
A = 0.078
(1 ms) yes
?- A is 0.79 / 10.
A = 0.079000000000000001
yes
Is there a way to select the desired number of decimal places in the resulting expr ?
ulrich@p0:/opt/gupu/gprolog$ git describe
v1.5.0-16-ge6354f6
ulrich@p0:/opt/gupu/gprolog$ ./src/TopComp/gprolog
GNU Prolog 1.5.1 (64 bits)
Compiled Feb 24 2022, 09:43:50 with gcc -std=gnu99
Copyright (C) 1999-2022 Daniel Diaz
| ?- length(L,L).
no % unexpected
| ?- length([a,b|L],L).
no % unexpected
See this justification.
I'm trying to find an ISO system (free / non-sicstus) that can handle the problem of
X #= 1.1*1.1
.
The BNR system is useful in that it provides an answer, whereby GNU does not:
uncaught exception: error(type_error(fd_evaluable,1.1000000000000001),(#=)/2)
What should be done about this?
Thank you - and I hear v2 may be coming out soon ;)
ulrich@p0:/opt/gupu/gprolog/src$ git describe
v1.5.0-31-gdd3f5ab
ulrich@p0:/opt/gupu/gprolog/src$ TopComp/gprolog
GNU Prolog 1.5.1 (64 bits)
Compiled Nov 29 2022, 12:37:19 with gcc -std=gnu99
Copyright (C) 1999-2022 Daniel Diaz
So is this version 1.5.0 or 1.5.1?
For example:
$ gprolog
GNU Prolog 1.5.1 (64 bits)
Compiled Feb 24 2023, 22:07:58 with /opt/local/bin/gcc-mp-12
Copyright (C) 1999-2023 Daniel Diaz
| ?- spy(foo/1).
Warning: spy foo/1 - no matching predicate
Warning: spy foo/1-1 - no matching predicate
yes
length(List, Length)
now sometimes produces a type_error(list,_)
when there is no instance of List
that is a list. In the past, length/2 uniformly failed in this case, as specified by the template and mode length(?term, ?integer)
.
See #4 ff:
| ?- length(2,0).
uncaught exception: error(type_error(list,2),top_level/0) % regression
| ?- length([_|2],0).
no % expected
| ?- length([_|2],N).
uncaught exception: error(type_error(list,2),top_level/0) % regression
| ?- length([_|2],1).
uncaught exception: error(type_error(list,2),top_level/0) % regression
| ?- length([_,_|2],1).
no % expected
In the following file:
Line 5 in b34288b
I think you meant to write:
* fix issue #7: length/2 now emits a type_error(list) only if the strict_iso flag is off
The predicate call_nth/2
could be optimized if hand-compiled:
$ cd /tmp/call_nth
$ cat call_nth.wam
% compiler: GNU Prolog 1.5.0
% file : call_nth.pl
file_name('/tmp/call_nth.pl').
predicate('$call_nth'/2,1,static,private,monofile,global,[
allocate(3),
get_variable(y(0),1),
% put_integer(1152921504606846974,1), % test overflow.
put_integer(0,1),
get_variable(y(1),1),
put_atom(call_nth,1),
put_integer(2,2),
put_atom(true,3),
call('$call'/4),
% Fast.
% math_load_value(y(1),0),
% call_c('Pl_Fct_Inc',[fast_call,x(0)],[x(0)]),
% Slow.
put_value(y(1),0),
put_variable(y(2),1),
% call(succ/2),
call_c('Pl_Set_Bip_Name_Untagged_2',[by_value],[call_nth,2]),
call_c('Pl_Succ_2',[boolean],[x(0),x(1)]),
put_value(y(2),0),
get_variable(y(1),0),
get_value(y(0),0),
deallocate,
proceed]).
$
Then to compiled it:
$ cd /tmp/call_nth
$ cat compile.sh
#!/bin/sh
# Source: http://www.gprolog.org/manual/html_node/gprolog009.html
PATH=$PATH:/tmp/gprolog/bin
# gplc -W call_nth.pl
gplc -M --comment call_nth.wam
gplc -S --comment call_nth.ma
gplc -c call_nth.s
gplc -o call_nth -s call_nth.o
$
And combined with:
$ cd /tmp/call_nth
$ cat call_nth.pl
'@call_nth'(G_0, N) :-
var(N), !,
'$call_nth'(G_0, N).
'@call_nth'(G_0, N) :-
integer(N),
N @>= 0, !,
N @> 0,
'$call_nth'(G_0, N), !.
'@call_nth'(_, N) :-
integer(N),
throw(error(domain_error(not_less_than_zero,N),'@call_nth'/2)).
'@call_nth'(_, N) :-
throw(error(type_error(integer,N),'@call_nth'/2)).
$
Benchmark:
$ cd /tmp/call_nth
$ PATH=$PATH:/tmp/gprolog/bin ./call_nth
GNU Prolog 1.6.0 (64 bits)
Compiled Jun 27 2023, 16:35:39 with gcc
Copyright (C) 1999-2023 Daniel Diaz
| ?- [call_nth].
compiling /tmp/call_nth/call_nth.pl for byte code...
/tmp/call_nth/call_nth.pl compiled, 44 lines read - 1965 bytes written, 7 ms
yes
| ?- [user].
compiling user for byte code...
query(N) :-
call_nth(repeat, N0),
N0 = N, !.
'@query'(N) :-
'@call_nth'(repeat, N0),
N0 = N, !.
user compiled, 38 lines read - 799 bytes written, 2916 ms
yes
| ?- query(16777216).
(7217 ms) yes
| ?- '@query'(16777216).
(5837 ms) yes
| ?- call_nth(repeat, 16777216).
(3348 ms) yes
| ?- '@call_nth'(repeat, 16777216).
(1501 ms) yes
| ?-
GNU Prolog installation:
$ cd /tmp
$ git clone https://github.com/didoudiaz/gprolog
$ cd gprolog/src
$ clear; make distclean; ./configure --with-install-dir=in-place --with-c-flags=debug; make -j$(nproc); make install
For the user, are the WAM instructions unstable to hand-compile it? Is there an alternative way to compile the instructions without creating a new binary?
Bug in the implementation of ~c
(code): the following calls are expected to print an A
:
| ?- format("~c", [65]).
yes
| ?- format('~c', [65]).
yes
Bug in the implementation of ~i
(ignore): the following calls are expected to omit the middle argument and thus print ac
:
| ?- format("~a~i~a", [a,b,c]).
ab
yes
| ?- format('~a~i~a', [a,b,c]).
ab
yes
The built-in format/2-3
predicates support using either an atom or a list of character codes for the format string (as de facto standard) but not using a list of characters. A main advantage of adding support for also writing format strings using a list of characters is that, if we use double-quoted terms for the format strings in calls to the format/2-3
predicates, the code will work independently of the current (standard) value of the double_quotes
flag.
P.S. Prolog systems supporting atoms, chars, and codes for the format string include ECLiPSe, LVM, Scryer Prolog, SICStus Prolog, SWI-Prolog, and YAP.
| ?- current_prolog_flag(max_integer, Max), ( integer(Max) -> succ(Max, S) ; true ).
Max = 1152921504606846975
S = -1152921504606846976, unexpected.
Expected:
?- current_prolog_flag(max_integer, Max),
( integer(Max) -> succ(Max, S) ; true ).
evaluation_error(int_overflow)
| Max = unbounded.
The end of 7.10.4 reads:
If the write-options list contains contradictory write-options,
the rightmost write-option is the one which applies.
But:
| ?- write_term(T,[variable_names(['Bad'=T]),variable_names(['Good'=T])]).
Bad % unexpected
yes
(ECLiPSe, Ichiban, IF, Minerva, Scryer, SICStus, SWI, Tau, Trealla, YAP all write Good)
Excluding the table related format specifiers, the only other format/2-3
test failures we now have are in the detection of errors in goals. The tests are:
test(lgt_format_2_partial_list_second_argument_1, error(instantiation_error)) :-
^^set_text_output(''),
{format("~d", [42| _])}.
test(lgt_format_2_too_many_arguments_1, errors([domain_error(_,_), consistency_error(_,_,_)])) :-
^^set_text_output(''),
{format("abc", [def])}.
test(lgt_format_2_too_many_arguments_2, errors([domain_error(_,_), consistency_error(_,_,_)])) :-
^^set_text_output(''),
{format("~a ~d", [abc, 42, def])}.
For the last two, there isn't a de facto standard exception. Most systems (that detect these errors), due use a domain error. E.g. in LVM:
?- format("~a ~d", [abc, 42, def]).
uncaught exception: error(domain_error(expected_number_of_arguments,[abc,42,def]),format([126,97,32,126,100],[abc,42,def]))
In Trealla Prolog:
?- format("~a ~d", [abc, 42, def]).
error(domain_error(empty_list,[def]),format/2).
$ gprolog
GNU Prolog 1.5.1 (64 bits)
Compiled May 7 2022, 16:09:46 with gcc
Copyright (C) 1999-2022 Daniel Diaz
| ?- bagof(X,X^!=X,Y).
Segmentation fault (core dumped)
| ?- fd_domain([A],0,1),A#==>0#>0/0.
no % unexpected
| ?- A=0, fd_domain([A],0,1),A#==>0#>0/0.
A = 0 % expected
Related to #86.
If a user defines e.g. the following meta-predicate:
:- meta_predicate(mp1(0)).
mp1(Goal) :-
call(Goal).
The predicate_property/2
predicate doesn't return the meta-predicate template:
| ?- predicate_property(mp1(_), P).
P = static ? ;
P = private ? ;
P = monofile ? ;
P = user ? ;
P = prolog_file(...) ? ;
P = prolog_line(2) ? ;
(1 ms) no
SWI, ECLiPSe
?- X is -0.0 * -0.0.
X = 0.0.
?- -0.0 is -0.0 * -0.0.
false.
%%%
GNU
| ?- X is -0.0 * -0.0.
X = 0.0
yes
| ?- -0.0 is -0.0 * -0.0.
yes % I would say no.
I tried this:
$ gprolog
GNU Prolog 1.5.0 (64 bits)
Compiled Apr 23 2022, 09:20:55 with gcc
Copyright (C) 1999-2022 Daniel Diaz
| ?- open('/tmp/empty.txt', write, S), close(S).
S = '$stream'(3)
(1 ms) yes
| ?- open('/tmp/empty.txt', read, _, [alias(empty), reposition(false), eof_action(reset), type(text)]).
yes
| ?- stream_property(S, alias(empty)), stream_property(S, end_of_stream(E)).
E = not
S = '$stream'(3)
yes
| ?- peek_char(empty, C).
C = end_of_file
yes
| ?- stream_property(S, alias(empty)), stream_property(S, end_of_stream(E)).
E = not
S = '$stream'(3)
yes
| ?- get_char(empty, C).
C = end_of_file
yes
| ?- stream_property(S, alias(empty)), stream_property(S, end_of_stream(E)).
E = not
S = '$stream'(3)
yes
| ?-
The same happens on a non-empty file.
Isn't ensure_loaded/1 a directive defined in the ISO core standard [ISO 7.4.2.8].
Currently it seems to be implemented by GNU Prolog as follows:
handle_directive(ensure_loaded, _, _) :-
!, warn('ensure_loaded directive not supported - directive ignored', []).
Wouldn't it be possible to bring ensure_loaded/1 to GNU Prolog. I understand
that it might be difficult, because of the various stages and artefact transformations
involved in GNU Prolog. But maybe a little separate compilation and later linking
would do the job. So that an ensure_loaded/1 directive would spawn a separate
compilation, put the artefact on a list, and at the end of a consult batch all
separate artefacts are linked together or otherwise integrated.
% GNU Prolog 1.5.1 (64 bits)
% Compiled Aug 31 2022, 15:45:21 with gcc
$ GLOBALSZ=160154120 gprolog
| ?- halt.
###
% GNU Prolog 1.6.0 (64 bits)
% Compiled Jun 2 2023, 13:40:45 with gcc
$ GLOBALSZ=160154120 gprolog
Fatal Error: Memory allocation fault
GNU/Linux 5.10
$ gprolog
GNU Prolog 1.5.0 (64 bits)
Compiled Jul 16 2021, 09:17:34 with gcc
Copyright (C) 1999-2021 Daniel Diaz
| ?- ^C
Prolog interruption (h for help) ? h
a abort b break
c continue e exit
d debug t trace
h/? help
Prolog interruption (h for help) ? d
Fatal Error: Segmentation Violation (bad address: 0x808)
$
When running the Logtalk distribution tests for the round/1
function, we get two odd failures:
! eclipse_round_1_06: failure (in 0.0 seconds)
! test assertion failed: 4==5
! in file logtalk/tests/prolog/functions/round_1/tests.lgt between lines 53-54
! eclipse_round_1_07: failure (in 0.0 seconds)
! test assertion failed: -4== -3
! in file logtalk/tests/prolog/functions/round_1/tests.lgt between lines 56-57
The tests are:
test(eclipse_round_1_06, true(X == 5)) :-
{X is round(4.5)}.
test(eclipse_round_1_07, true(X == -3)) :-
{X is round(-3.5)}.
But, like other compilers that pass these tests:
| ?- current_prolog_flag(integer_rounding_function, Value).
Value = toward_zero
yes
| ?- X is 9^9^2.
uncaught exception: error(evaluation_error(int_overflow),(is)/2) % expected
| ?- X is 9^9^3.
uncaught exception: error(evaluation_error(float_overflow),(is)/2) % unexpected, no float involved
ulrich@p0:/opt/gupu/gprolog$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
src/EnginePl/cpp_headers
nothing added to commit but untracked files present (use "git add" to track)
And before:
ulrich@p0:/opt/gupu/gprolog$ git pull
remote: Enumerating objects: 37, done.
remote: Counting objects: 100% (37/37), done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 19 (delta 18), reused 19 (delta 18), pack-reused 0
Unpacking objects: 100% (19/19), done.
From https://github.com/didoudiaz/gprolog
004cbf1..d9333a3 master -> origin/master
Updating 004cbf1..d9333a3
error: Your local changes to the following files would be overwritten by merge:
src/Pl2Wam/wam_emit.wam
Please, commit your changes or stash them before you can merge.
Aborting
ulrich@p0:/opt/gupu/gprolog$ git reset --hard
which solved it.
I'm testing GNU Prolog 1.5.0 (x86_64 / Windows 10 with MSVC++) on Windows 10. No matter the path I pass as first argument, I always get a error(system_error('No such file or directory'), directory_files/2)
or error(system_error('No error'),directory_files/2)
exceptions.
| ?- X = (\+X).
cannot display cyclic term for X
yes
| ? X = (\+X), write(X).
\+ \+ \+ \+ \+ \+ \+ \+ \+ \+ \+ \+ \+ \+ \+ \+ \+
:
:
\+ \+ \+ \+ \+ \+Segmentation fault (core dumped)
$
Would it be possible to add a copy_file/2
predicate?
I'm trying to use gplc
on Windows 10. GNU Prolog was installed using the latest setup-gprolog-1.5.1-msvc-x64.exe
beta installer. The gplc
command is being called from a new Logtalk PowerShell embedding script. The same embedding examples that work e.g. in macOS, on Windows 10 end with a compilation failed
message with no hint of what went wrong. Is there a dependency that I may be missing on Windows 10 that's required for successfully using gplc
? Any suggestions on how to diagnose this issue?
ulrich@p0:/opt/gupu/gprolog$ git describe
v1.5.0-19-gb0a17f5
ulrich@p0:/opt/gupu/gprolog$ src/TopComp/gprolog
GNU Prolog 1.5.1 (64 bits)
Compiled Feb 24 2022, 09:43:50 with gcc -std=gnu99
Copyright (C) 1999-2022 Daniel Diaz
| ?- L=[a|n],append([a|L],n,L).
no % expected
| ?- append([a|L],n,L).
L = [a|n] ? % unexpected
(3 ms) yes
I recently added some more tests for the Prolog standard bagof/3
and setof/3
predicates to the current Logtalk git version. With the latest GNU Prolog git version (), I get:
$ logtalk_tester -p gnu
% Batch testing started @ 2023-03-22 18:39:06
% Logtalk version: 3.64.0-b01
% GNU Prolog version: 1.5.1
%
% logtalk/tests/prolog/predicates/bagof_3
% 23 tests: 1 skipped, 21 passed, 1 failed (0 flaky)
% completed tests from object tests in 3 seconds
% clause coverage n/a
%
% Compilation errors/warnings and failed unit tests
% (compilation errors/warnings might be expected depending on the test)
! lgt_bagof_3_23: failure (in 0.0 seconds)
! test goal failed but should have thrown an error:
! expected error(existence_error(procedure,foobar/1),A)
! in file logtalk/tests/prolog/predicates/bagof_3/tests.lgt between lines 169-170
%
% Skipped tests
logtalk/tests/prolog/predicates/bagof_3/tests.lgt - lgt_bagof_3_22 @ tests
%
% Failed tests
logtalk/tests/prolog/predicates/bagof_3/tests.lgt - lgt_bagof_3_23 @ tests
%
% 1 test sets: 1 completed, 0 skipped, 0 broken, 0 timedout, 0 crashed
% 23 tests: 1 skipped, 21 passed, 1 failed (0 flaky)
%
% Batch testing ended @ 2023-03-22 18:39:10
Similar for setof/3
. The failing test is:
test(lgt_bagof_3_23, errors([existence_error(procedure,foobar/1), existence_error(procedure,':'(user,foobar/1))])) :-
{bagof(X, foobar(X), _)}.
If we try the goal at the top-level, we do get the expected exception:
| ?- bagof(X, foobar(X), _).
uncaught exception: error(existence_error(procedure,foobar/1),bagof/3)
The tests are run using a catch/3
goal that catches all exceptions. Thus, this may be a dereferencing bug?
ulrich@p0:/opt/gupu/gprolog/src$ uname -a
Linux p0 3.13.0-170-generic #220-Ubuntu SMP Thu May 9 12:40:49 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
ulrich@p0:/opt/gupu/gprolog/src$ git describe
v1.5.0-1-g8a8220d
ulrich@p0:/opt/gupu/gprolog/src$ ./TopComp/gprolog
GNU Prolog 1.5.0 (64 bits)
Compiled Aug 8 2021, 18:10:30 with gcc -std=gnu99
Copyright (C) 1999-2021 Daniel Diaz
| ?- between(59,65,E), X is 2^E.
E = 59
X = 576460752303423488 ? ; % expected
E = 60
X = -1152921504606846976 ? ; % unexpected
E = 61
X = 0 ? ; % unexpected
E = 62
X = 0 ? ; % unexpected
/* E = 63 */
uncaught exception: error(evaluation_error(int_overflow),(is)/2) % expected
And:
| ?- between(59,64,E), catch(X is 2^2^E,error(Error,_),true).
E = 59
Error = evaluation_error(float_overflow) ? ; % expected
E = 60
Error = type_error(float,2) ? ; % unexpected
E = 61
X = 1 ? ; % unexpected
E = 62
X = 1 ? ; % unexpected
E = 63
Error = evaluation_error(int_overflow) ? ; % expected
Even after a make clean...
| ?- call_nth(repeat,Nth).
uncaught exception: error(existence_error(procedure,call_nth/2),top_level/0)
Note that without call_nth/2
testing is practically impossible.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.