Merge branch 'master' of https://github.com/mthom/rusty-wam
This commit is contained in:
22
README.md
22
README.md
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
).
|
||||
|
||||
@@ -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)
|
||||
).
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user