things to do c: - profile=fast (unordered :p)

triska

  1. represent strings as packed arrays (scryer)
  2. test conformity better
  3. reliable timeout and space-out errors
  4. implement attributed variables
  5. writing terms should be moved to prolog code
  6. support quad testing

uwn https://www.complang.tuwien.ac.at/ulrich/flowlog-prolog/

  1. compilation on older system does not work
    ulrich@p0:/opt/gupu/flowlog$ make
    cc -O2 -Wall -Wextra -pthread flowlog.c -lm  -o flowlog
    flowlog.c:41:23: fatal error: stdatomic.h: No such file or directory
     #include 
                           ^
    compilation terminated.
    make: *** [flowlog] Error 1
    ulrich@p0:/opt/gupu/flowlog$ cc --version
    cc (Ubuntu 4.8.4-2ubuntu1~14.04.4) 4.8.4
    Copyright (C) 2013 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  1. testing number_chars/2 Because of #3 and #4, I cannot use the current test table, so I resorted to the old one. Please go through it. Problems start with #9, #17, #21.
    ulrich@gupu:/opt/gupu/flowlog$ ./flowlog 
    Flowlog (pthreads)
    Type 'help.' for help, 'halt.' to exit.
    ?- number_chars(1,[_,[]]).
    error(instantiation_error,/(number_chars,2)), unexpected.
       type_error(character,[]). % expected, but not found
    ?- number_chars(N,['3',.]).
    N = 3.0, unexpected.
       syntax_error(...). % expected, but not found
    ?- number_chars(N,[-,' ','1']).
    flowlog: fatal error (240): flowlog: unexpected token while parsing term
  1. writeq ignores operators Before improving read-ing, consider writeq-ing. Such that you always write valid syntax. So the first to address would be:

    1. s#1
    2. s#13
    3. s#27
    4. s#35
    5. s#36
  2. integer overflow incorrect

    ?- 62 = E, X is 2^E-1+2^E.
    X = 9223372036854775807 % good
    ?- 62 = E, X is 2^E-1+2^E+1.
    X = -9223372036854775808, unexpected.
    ?- X is 2^63.
    error(evaluation_error(undefined),/(is,2)), unexpected.
       evaluation_error(int_overflow) % expected exceptional value (3.66, 7.9.2 e, 7.12.2 g, 9.1.2)
    |  X = 9223372036854775808. % current_prolog_flag(bounded,false)
current_prolog_flag(bounded,false) in SICStus, Scryer, Trealla, YAP, B, IF, IV, SWI, ECLiPSe, Ciao. Internally, these implementations have two versions of integers, the small immediate ones and the large one which reside on the heap. In this manner the immediate integers may use less than 60..63 bits, which frees tagging space for other uses.

Only GNU, 1ban with current_prolog_flag(bounded,true) and correct overflows.

GNU:
    | ?- 59 = E, X is 2^E-1+2^E.

    X = 1152921504606846975

    yes
    | ?- 59 = E, X is 2^E-1+2^E+1.
    uncaught exception: error(evaluation_error(int_overflow),(is)/2)
1ban:
    ?- 62 = E, X is 2^E-1+2^E.
    X = 9223372036854775807.
    ?- 62 = E, X is 2^E-1+2^E+1.
    2026/01/02 11:43:26 error(evaluation_error(int_overflow),is/2)
XSB, Cx, Minerva are also bounded, but miss some overflows.

In general, it is much easier to be conforming with unbounded integers, because this overflow evaluation_error never occurs which limits arithmetical optimizations. And one has to test for overflows anyway.
  1. select/3 not conforming Since 2011 select/3 is defined without any errors. Just with two clauses. (Actually, it was commonly defined like that since at least 1983. C&M:1981 did not use it) Thus the following is not conforming:
    ?- select(X, Xs, Ys).
    false, unexpected.
    ?- select(X, Xs, Xs).
    false, unexpected. % see p.p.5.4
    ?- select(X,Xs,[1,2,3]).
    false, unexpected.
    % this is the expected answer:
       Xs = [X,1,2,3]
    ;  Xs = [1,X,2,3]
    ;  Xs = [1,2,X,3]
    ;  Xs = [1,2,3,X].
    ?- select(X, [Y|nonlist], Xs).
    error(type_error(list,[_G0|nonlist]),/(select1,3)), unexpected.
This type error would make sense, if the template and modes subclause would indicate ?list for the second argument, but it reads in p.p.5.2
        select(?term, ?term, ?term)

    ?- Xs = [a|Xs], ( true ; catch(select(X, Xs, Ys), Err, true ) ).
       Xs = [a,a,a,a,a|...]
    ;  Xs = [a,a,a,a,a|...], error(representation_error(term),/(select1,3)), unexpected.
    % expected behaviour:
       sto,
       false % occurs-check
    |  sto,
       Xs = [a|Xs] % rational trees
    ;  Xs = [a|Xs], X = a, Ys = [a|Ys]
    ;  Xs = [a|Xs], X = a, Ys = [a|Ys]
    ;  ..., ad_infinitum
    |  sto,
       representation_error(term).
  1. git clone problem with old system
    ulrich@p0:/tmp$ git clone https://git.liminal.cafe/byakuren/flowlog.git
    Cloning into 'flowlog'...
    fatal: unable to access 'https://git.liminal.cafe/byakuren/flowlog.git/': gnutls_handshake() failed: Handshake failed
    ulrich@p0:/tmp$ cat /etc/issue
    Ubuntu 14.04.6 LTS \n \l
This does not happen with github. There I follow various systems like Scryer, Trealla. 


A representation error can only be issued at a point in time when a goal attempts to create some term that cannot be represented. So this error prevents the creation of something. Thus the goal Xs = [a|Xs] may issue a representation error, if unification is defined in such a manner (e.g., set_prolog_flag(occurs_check, error) in Scryer or Trealla). But from above answer it is clear that this goal succeeds, and thus the infinite tree is created. (Do not call it an infinite term since terms are defined such that there are no cyclic structures in them). 
  1. append/3 does not work (Example from the Prolog prologue)
    ?- append([a], Ys, Zs).
    Segmentation fault (core dumped), unexpected.
       Zs = [a|Ys]. % expected, but not found

v4.6.5

  1. infinite loop does not work
    inf :-
       inf.

    ?- inf.
    Segmentation fault (core dumped), unexpected.
       loops % expected
    |  resource_error(...). % if you insist ...