This commit is contained in:
Mark Thom
2020-04-28 01:41:11 -06:00
9 changed files with 67 additions and 47 deletions

View File

@@ -40,7 +40,7 @@ Extend Scryer Prolog to include the following, among other features:
- [x] Support for `verify_attributes/3`
- [x] Support for `attribute_goals/2` and `project_attributes/2`
- [x] `call_residue_vars/2`
- [x] `if_` and related predicates, following the developments of the
- [x] `if_/3` and related predicates, following the developments of the
paper "Indexing `dif/2`".
- [x] All-solutions predicates (`findall/{3,4}`, `bagof/3`, `setof/3`, `forall/2`).
- [x] Clause creation and destruction (`asserta/1`, `assertz/1`,
@@ -273,6 +273,24 @@ described in [*Tabling as a Library with Delimited
Control*](https://biblio.ugent.be/publication/6880648/file/6885145.pdf)
by Desouter et. al.
### Constraint Logic Programming (CLP)
Scryer Prolog provides excellent support for Constraint Logic
Programming (CLP), which is the amalgamation of
Logic Programming (LP) and Constraints.
In addition to built-in support for [`dif/2`](src/prolog/lib/dif.pl),
[`freeze/2`](src/prolog/lib/freeze.pl),
[CLP()](src/prolog/lib/clpz.pl) and [CLP(B)](src/prolog/lib/clpb.pl),
Scryer provides a convenient way to implement new user-defined
constraints: *Attributed variables* are available via
[`library(atts)`](src/prolog/lib/atts.pl) as in SICStus Prolog,
which is one of the most sophisticated and fastest constraint systems
in existence.
These features make Scryer Prolog an ideal platform for teaching,
learning and developing portable CLP applications.
### Modules
Scryer has a simple predicate-based module system. It provides a
@@ -343,6 +361,8 @@ The modules that ship with Scryer Prolog are also called
for measuring the performance of your code.
* [`cont`](src/prolog/lib/cont.pl)
Provides *delimited continuations* via `reset/3` and `shift/1`.
* [`random`](src/prolog/lib/random.pl)
Probabilistic predicates and random number generators.
To read contents of external files, use `phrase_from_file/2` from
[`library(pio)`](src/prolog/lib/pio.pl) to apply a DCG to

View File

@@ -1,9 +1,11 @@
:- module(arithmetic, [msb/2, lsb/2]).
:- use_module(library(error)).
lsb(X, N) :-
builtins:must_be_number(X, lsb/2),
( \+ integer(X) -> throw(error(type_error(integer, X), lsb/2))
; X < 1 -> throw(error(domain_error(not_less_than_one, X), lsb/2))
( \+ integer(X) -> type_error(integer, X, lsb/2)
; X < 1 -> domain_error(not_less_than_one, X, lsb/2)
; builtins:can_be_number(N, lsb/2),
X1 is X /\ (-X),
msb_(X1, -1, N)
@@ -11,8 +13,8 @@ lsb(X, N) :-
msb(X, N) :-
builtins:must_be_number(X, msb/2),
( \+ integer(X) -> throw(error(type_error(integer, X), msb/2))
; X < 1 -> throw(error(domain_error(not_less_than_one, X), msb/2))
( \+ integer(X) -> type_error(integer, X, msb/2)
; X < 1 -> domain_error(not_less_than_one, X, msb/2)
; builtins:can_be_number(N, msb/2),
X1 is X >> 1,
msb_(X1, 0, N)

View File

@@ -34,7 +34,7 @@
:- use_module(library(random)).
:- use_module(library(pairs)).
:- use_module(library(dcgs)).
:- use_module(library(error), []).
:- use_module(library(error), [domain_error/3, type_error/3]).
:- attribute
clpb/1,
@@ -98,16 +98,10 @@ instantiation_error(_, Goal-Arg) :-
domain_error(Expectation, Term) :-
domain_error(Expectation, Term, unknown(Term)-1).
domain_error(Expectation, Term, Goal-Arg) :-
throw(error(domain_error(Expectation, Term), domain_error(Goal, Arg, Expectation, Term))).
type_error(Expectation, Term) :-
type_error(Expectation, Term, unknown(Term)-1).
type_error(Expectation, Term, Goal-Arg) :-
throw(error(type_error(Expectation, Term), type_error(Goal, Arg, Expectation, Term))).
partition(Pred, Ls0, As, Bs) :-
include(Pred, Ls0, As),
exclude(Pred, Ls0, Bs).

View File

@@ -115,7 +115,7 @@
:- use_module(library(iso_ext)).
:- use_module(library(dcgs)).
:- use_module(library(terms)).
:- use_module(library(error), []).
:- use_module(library(error), [domain_error/3, type_error/3]).
:- use_module(library(si)).
:- use_module(library(freeze)).
@@ -185,16 +185,9 @@ instantiation_error(_, Goal-Arg) :-
domain_error(Expectation, Term) :-
domain_error(Expectation, Term, unknown(Term)-1).
domain_error(Expectation, Term, Goal-Arg) :-
throw(error(domain_error(Expectation, Term), domain_error(Goal, Arg, Expectation, Term))).
type_error(Expectation, Term) :-
type_error(Expectation, Term, unknown(Term)-1).
type_error(Expectation, Term, Goal-Arg) :-
throw(error(type_error(Expectation, Term), type_error(Goal, Arg, Expectation, Term))).
partition(Pred, Ls0, As, Bs) :-
include(Pred, Ls0, As),

View File

@@ -1,5 +1,9 @@
:- module(error, [must_be/2,
can_be/2]).
can_be/2,
instantiation_error/1,
domain_error/3,
type_error/3
]).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Written September 2018 by Markus Triska (triska@metalevel.at)
@@ -32,10 +36,10 @@ must_be(Type, Term) :-
must_be_(Type, _) :-
var(Type),
instantiation_error(Type).
instantiation_error(must_be/2).
must_be_(var, Term) :-
( var(Term) -> true
; throw(error(uninstantiation_error, _))
; throw(error(uninstantiation_error, must_be/2))
).
must_be_(integer, Term) :- check_(integer, integer, Term).
must_be_(atom, Term) :- check_(atom, atom, Term).
@@ -43,12 +47,12 @@ must_be_(list, Term) :- check_(ilist, list, Term).
must_be_(type, Term) :- check_(type, type, Term).
check_(Pred, Type, Term) :-
( var(Term) -> instantiation_error(Term)
( var(Term) -> instantiation_error(must_be/2)
; call(Pred, Term) -> true
; type_error(Type, Term)
; type_error(Type, Term, must_be/2)
).
ilist(V) :- var(V), instantiation_error(V).
ilist(V) :- var(V), instantiation_error(must_be/2).
ilist([]).
ilist([_|Ls]) :- ilist(Ls).
@@ -76,7 +80,7 @@ can_be(Type, Term) :-
must_be(type, Type),
( var(Term) -> true
; can_(Type, Term) -> true
; type_error(Type, Term)
; type_error(Type, Term, can_be/2)
).
can_(integer, Term) :- integer(Term).
@@ -92,11 +96,11 @@ list_or_partial_list([_|Ls]) :-
Shorthands for throwing ISO errors.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
instantiation_error(_Term) :-
throw(error(instantiation_error, _)).
instantiation_error(Context) :-
throw(error(instantiation_error, Context)).
domain_error(Type, Term) :-
throw(error(domain_error(Type, Term), _)).
domain_error(Type, Term, Context) :-
throw(error(domain_error(Type, Term), Context)).
type_error(Type, Term) :-
throw(error(type_error(Type, Term), _)).
type_error(Type, Term, Context) :-
throw(error(type_error(Type, Term), Context)).

View File

@@ -148,7 +148,7 @@ element_gluevar(glue(_,V), N, N) --> [V].
cells([], Args, Tab, Es) -->
( { Args == [] } -> cell(Tab, Tab, Es)
; { domain_error(no_remaining_arguments, Args) }
; { domain_error(no_remaining_arguments, Args, format_//2) }
).
cells([~,~|Fs], Args, Tab, Es) --> !,
cells(Fs, Args, Tab, [chars("~")|Es]).
@@ -253,15 +253,12 @@ cells([~|Fs0], Args0, Tab0, Es) -->
cells(Fs, Args, Tab, []).
cells([~,C|_], _, _, _) -->
{ atom_chars(A, [~,C]),
domain_error(format_string, A) }.
domain_error(format_string, A, format_//2) }.
cells(Fs0, Args, Tab, Es) -->
{ phrase(upto_what(Fs1, ~), Fs0, Fs),
Fs1 = [_|_] },
cells(Fs, Args, Tab, [chars(Fs1)|Es]).
domain_error(Type, Term) :-
throw(error(domain_error(Type, Term), _)).
n_newlines(0) --> !.
n_newlines(1) --> !, [newline].
n_newlines(N0) --> { N0 > 1, N is N0 - 1 }, [newline], n_newlines(N).
@@ -498,7 +495,7 @@ listing(PI) :-
Arity = Arity0
; PI = Name//Arity0 ->
Arity is Arity0 + 2
; throw(error(type_error(predicate_indicator, PI), listing/1))
; type_error(predicate_indicator, PI, listing/1)
),
functor(Head, Name, Arity),
\+ \+ clause(Head, Body), % only true if there is at least one clause

View File

@@ -1,11 +1,12 @@
:- module(pio, [phrase_from_file/2]).
:- use_module(library(dcgs)).
:- use_module(library(error)).
phrase_from_file(NT, File) :-
( var(File) -> throw(error(instantiation_error, phrase_from_file/2))
( var(File) -> instantiation_error(phrase_from_file/2)
; (\+ atom(File) ; File = []) ->
throw(error(domain_error(source_sink, File), phrase_from_file/2))
domain_error(source_sink, File, phrase_from_file/2)
; '$file_to_chars'(File, Chars),
phrase(NT, Chars)
).

View File

@@ -1,5 +1,13 @@
:- module(random, [maybe/0, random/1, random_integer/3, set_random/1]).
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
To retain desirable declarative properties, predicates that internally
use random numbers should be equipped with an argument that specifies
the random seed. This makes everything completely reproducible.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
:- use_module(library(error)).
% succeeds with probability 0.5.
maybe :- '$maybe'.
@@ -16,9 +24,9 @@ random_integer(Lower, Upper, R) :-
( (var(Lower) ; var(Upper)) ->
throw(error(instantiation_error, random_integer/3))
; \+ integer(Lower) ->
throw(error(domain_error(integer, Lower), random_integer/3))
domain_error(integer, Lower, random_integer/3)
; \+ integer(Upper) ->
throw(error(domain_error(integer, Upper), random_integer/3))
domain_error(integer, Upper, random_integer/3)
; Upper > Lower,
random(R0),
R is floor((Upper - Lower) * R0 + Lower)
@@ -41,11 +49,11 @@ rnd_(N, R0, R) :-
set_random(Seed) :-
( nonvar(Seed) ->
( Seed = seed(S) ->
( var(S) -> throw(error(instantiation_error, set_random/1))
( var(S) -> instantiation_error(set_random/1)
; integer(S) -> '$set_seed'(S)
; throw(error(type_error(integer(S), set_random/1)))
; type_error(integer, S, set_random/1)
)
)
; throw(error(instantiation_error, set_random/1))
; instantiation_error(set_random/1)
).

View File

@@ -13,13 +13,14 @@
:- use_module(library(format)).
:- use_module(library(iso_ext)).
:- use_module(library(error)).
max_sleep_time(0xfffffffffffffbff).
sleep(T) :-
builtins:must_be_number(T, sleep),
( T < 0 ->
throw(error(domain_error(not_less_than_zero, T), sleep/1))
domain_error(not_less_than_zero, T, sleep/1)
; max_sleep_time(N), T > N ->
throw(error(reprensentation_error(max_sleep_time), sleep/1))
; '$sleep'(T)