Motivation and considerations:
- A Scryer certainly needs a raven. Ravens are among the most
intelligent animals on earth.
- When writing Prolog programs, a few strokes are often enough.
- Purple is the colour most associated with magic and royalty,
indicating the almost surreal and pure features provided by Scryer,
in the lineage of Marseille Prolog.
- The shape of the silhouette looks a bit like an "S" for "Scryer".
- A square which surrounds the image is traditionally associated with
finishing a proof (square, Latin "quadratum", has the same starting
letters as "quod erat demonstrandum").
I call this raven: *Cryer*. Cryer is an archaic spelling for "crier",
an officer who makes public announcements in a court of justice.
The Prolog top-level likewise makes announcements about what is true.
This seems to be a good compromise: The API now strongly encourages
lists of characters, which are ideally suited to represent text, and
also allows lists of bytes if the encoding(octet) option is used.
This is to focus more on the intended core representation of text: In
Prolog, text is ideally represented as a list of characters, and this
is what we want to encourage, especially given Scryer's compact
representation for strings.
For the time being, library(crypto) still also supports lists of bytes in
several predicates. This will likely be removed at some point in the
future. Please use lists of characters to make your code future-proof.
Notably, this format requires that the public key also be present.
This format is what ed25519_new_keypair/1 generates, and it is
strongly encouraged for higher security.
Support for lists of bytes may be dropped from library(crypto). Use
lists of characters to make your code future-proof. Lists of
characters will always be supported due to their compactness,
and because Prolog applications should move towards characters.
Due to the way the counter is constructed in the HKDF specification,
the requested output length can be at most 255 times the size of the
digest algorithm's output.
Reported by @notoria in #527. Many thanks!
This is useful to generate keys and initialization vectors
from suitable input keying material, so that future predicates
for symmetric encryption can be used with appropriate parameters.
This is useful to establish shared secrets, using ECDH key exchange.
Note that CLP(ℤ) goal expansion is currently disabled due to #445,
and this slows down the computations considerably for the time being.
For instance, consider:
t(X) :- X #= 1.
We *cannot* expand this to:
?- listing(t/1).
t(A) :-
( integer(A) ->
A=:=A
; ( var(A) ->
true
; true,
clpz:clpz_equal(A,A)
)
).
Also, a new binding *must not* be dragged outside of disjunctions,
since the code may look for example like this:
i(X) :-
( X #= 3
; X #= 4
).
This commit fixes such issues, and still rewrites CLP(ℤ) expressions
as far as possible already at compilation time.
For example:
n(X) :- X #= 1+3.
This is now compiled to (note that 1+3 is evaluated to 4):
?- listing(n/1).
n(A) :-
( integer(A) ->
A=:=4
; ( var(A) ->
A=4
; B=4,
clpz:clpz_equal(A,B)
)
).
Ideally, it should be compiled to:
n(4).
This is especially important because a few of our names diverge from
ctype(3), and we better inform programmers when the type they are
using is not available at all.
Example:
:- dynamic(a/1).
a(X) :- X = true, b(X).
Yielding:
?- listing(a/1).
%@ a(A) :-
%@ A=true,
%@ b(A).
%@ true.
listing/1 only works for predicates and DCGs that are declared dynamic/1.
This works best when used in tandem with ~N+, since it is currently
equivalent to ~0| and does not take the actual text position into account.
However, when using relative positions, this works as intended.
This is to accommodate goals that are used for their side-effects,
when we are interested in their output.
Examples:
?- portray_clause((a :- a)).
a :-
a.
true
; false.
?- format("hello~w~n", [!]).
hello!
true
; false.
The preceding use of atom_length/2 already ensures that C has the
correct type (i.e., atom). However, its domain may still be wrong,
if its length is greater than 1.
The preceding use of atom_length/2 already ensures that C has the
correct type (i.e., atom). However, its domain may still be wrong,
if its length is greater than 1.
Pairs must be keysorted and may also contain variables as keys.
Examples:
?- group_pairs_by_key([1-a,1-b,2-c], Ps).
Ps = [1-[a,b],2-[c]].
?- group_pairs_by_key([X-a,X-b,2-c], Ps).
Ps = [X-[a,b],2-[c]].