Commit Graph

1116 Commits

Author SHA1 Message Date
Markus Triska
567af2648c support must_be(var, ...) 2019-10-16 19:18:38 +02:00
Mark Thom
42a3bdc357 eliminate lingering attribute goals v0.8.112 2019-10-16 11:38:33 -03:00
Mark Thom
b6a2e26a4f bump toml version number to package clpb on crates v0.8.111 2019-10-16 09:59:41 -03:00
Mark Thom
1557e4705a Merge pull request #204 from triska/master
ADDED: CLP(B), Constraint Logic Programming over Boolean Variables
2019-10-16 02:45:21 -03:00
Markus Triska
ee32e49528 ADDED: CLP(B), Constraint Logic Programming over Boolean Variables
library(clpb) provides CLP(B), Constraint Logic Programming over
Boolean variables. It is a SAT solver that seamlessly integrates into
Prolog in the sense that logic variables are used to state constraints
and report solutions. This library can be used to model and solve many
combinatorial problems such as verification, allocation and covering
tasks.

CLP(B) is an instance of the general CLP(X) scheme, extending logic
programming with reasoning over specialised domains.

The implementation is based on reduced and ordered Binary Decision
Diagrams (BDDs).

Usage examples of this library are available in a public git
repository:

    https://github.com/triska/clpb

For more information, benchmarks and publications visit:

    https://www.metalevel.at/clpb/

The interface of this library is consciously kept compatible with the
CLP(B) solver of SICStus Prolog, which served as the main inspiration
of this library. Many thanks to Mats Carlsson for his elegant example!

It is my hope that library(clpb) will allow a port of cTI, and —
eventually — of Ulrich Neumerkel's GUPU to Scryer Prolog.

                         Boolean expressions
                         ===================

A Boolean expression is one of:

     0                 false
     1                 true
     variable          unknown truth value
     atom              universally quantified variable
     ~ Expr            logical NOT
     Expr + Expr       logical OR
     Expr * Expr       logical AND
     Expr # Expr       exclusive OR
     Var ^ Expr        existential quantification
     Expr =:= Expr     equality
     Expr =\= Expr     disequality (same as #)
     Expr =< Expr      less or equal (implication)
     Expr >= Expr      greater or equal
     Expr < Expr       less than
     Expr > Expr       greater than
     card(Is,Exprs)    see below
     +(Exprs)          see below
     *(Exprs)          see below

where Expr again denotes a Boolean expression.

The Boolean expression card(Is,Exprs) is true iff the number of true
expressions in the list Exprs is a member of the list Is of
integers and integer ranges of the form From-To.

+(Exprs) and *(Exprs) denote, respectively, the disjunction and
conjunction of all elements in the list Exprs of Boolean
expressions.

Atoms denote parametric values that are universally quantified. All
universal quantifiers appear implicitly in front of the entire
expression. In residual goals, universally quantified variables always
appear on the right-hand side of equations. Therefore, they can be
used to express functional dependencies on input variables.

                         Interface predicates
                         ====================

The most frequently used CLP(B) predicates are:

    * sat(+Expr)
      True iff the Boolean expression Expr is satisfiable.

    * taut(+Expr, -T)
      If Expr is a tautology with respect to the posted constraints, succeeds
      with T = 1. If Expr cannot be satisfied, succeeds with T = 0.
      Otherwise, it fails.

    * labeling(+Vs)
      Assigns truth values to the variables Vs such that all constraints
      are satisfied.

The unification of a CLP(B) variable X with a term T is equivalent
to posting the constraint sat(X=:=T).

                               Examples
                               ========

Here is an example session with a few queries and their answers:

    ?- use_module(library(clpb)).
    true.

    ?- sat(X*Y).
    X = Y, Y = 1.

    ?- sat(X * ~X).
    false.

    ?- taut(X * ~X, T).
    T = 0,
    sat(X=:=X).

    ?- sat(X^Y^(X+Y)).
    sat(X=:=X),
    sat(Y=:=Y).

    ?- sat(X*Y + X*Z), labeling([X,Y,Z]).
    X = Z, Z = 1, Y = 0 ;
    X = Y, Y = 1, Z = 0 ;
    X = Y, Y = Z, Z = 1.

    ?- sat(X =< Y), sat(Y =< Z), taut(X =< Z, T).
    T = 1,
    sat(X=:=X*Y),
    sat(Y=:=Y*Z).

    ?- sat(1#X#a#b).
    sat(X=:=a#b).

The pending residual goals constrain remaining variables to Boolean
expressions and are declaratively equivalent to the original query.
The last example illustrates that when applicable, remaining variables
are expressed as functions of universally quantified variables.

                            Obtaining BDDs
                            ==============

By default, CLP(B) residual goals appear in (approximately) algebraic
normal form (ANF). This projection is often computationally expensive.

Assert the fact clpb:clpb_residuals(bdd) to see the BDD representation
of all constraints. This results in faster projection to residual
goals, and is also useful for learning more about BDDs.

For example:

    ?- asserta(clpb:clpb_residuals(bdd)).
    true.

    ?- sat(X#Y).
    node(3)- (v(X, 0)->node(2);node(1)),
    node(1)- (v(Y, 1)->true;false),
    node(2)- (v(Y, 1)->false;true).

Note that this representation cannot be pasted back on the toplevel,
and its details are subject to change. Use copy_term/3 to obtain
such answers as Prolog terms.

The variable order of the BDD is determined by the order in which the
variables first appear in constraints. To obtain different orders,
you can for example use:

    ?- sat(+[1,Y,X]), sat(X#Y).
    node(3)- (v(Y, 0)->node(2);node(1)),
    node(1)- (v(X, 1)->true;false),
    node(2)- (v(X, 1)->false;true).

                           Monotonic CLP(B)
                           ================

In the default execution mode, CLP(B) constraints are not monotonic.
This means that adding constraints can yield new solutions. For
example:

    ?-          sat(X=:=1), X = 1+0.
    false.

    ?- X = 1+0, sat(X=:=1), X = 1+0.
    X = 1+0.

This behaviour is highly problematic from a logical point of view, and
it may render declarative debugging techniques inapplicable (see
https://www.metalevel.at/prolog/debugging for more information).

Assert the fact clpb:monotonic to make CLP(B) monotonic. If this
mode is enabled, then you must wrap CLP(B) variables with the functor
v/1. For example:

    ?- asserta(clpb:monotonic).
    true.

    ?- sat(v(X)=:=1#1).
    X = 0.

Enjoy!
2019-10-16 06:57:43 +02:00
Mark Thom
ca27234275 deallocate old stack frames (#201), start using tags, fix a panic! associated with partial strings v0.8.110 2019-10-15 22:54:12 -06:00
Mark Thom
9f7d89a3e8 re: issue #199 2019-10-15 02:37:01 -06:00
Mark Thom
c4269b87c2 re: issues #200, #201 2019-10-15 00:42:55 -06:00
Mark Thom
be7f855d7a Merge pull request #198 from XVilka/patch-2
Fix #139 - Run tests on Travis
2019-10-14 10:18:43 -03:00
Mark Thom
734f103f0a Merge pull request #197 from dingelish/edition
Upgrade to edition
2019-10-14 10:18:18 -03:00
Anton Kochkov
cdc47c1a7b Run tests on Travis 2019-10-14 17:46:09 +08:00
Yu Ding
adb469f627 Upgrade to edition. Bump up edition in Cargo.toml 2019-10-14 00:23:32 -07:00
Mark Thom
7f297eb064 Merge pull request #191 from dingelish/master
Fix some old Rust codes
2019-10-14 00:59:03 -03:00
Mark Thom
83ead46e13 re: issue #196 2019-10-14 00:07:22 -06:00
Mark Thom
da89b1af63 handle TCO when setting up verify_attributes interrupts 2019-10-13 14:13:52 -06:00
Mark Thom
249b613e36 remove nondeterminism from put_atts as a result of lists.pl reversion 2019-10-12 19:57:08 -06:00
Mark Thom
1d41489381 correct off by 1 error in verify_attrs_interrupt, revert to previous lists.pl 2019-10-12 19:14:33 -06:00
Mark Thom
8c4c70b089 fix verify_attributes_stepper bug: proceed now considered a head instruction 2019-10-12 03:26:50 -06:00
Mark Thom
5893ff4231 correct latest out of bounds panic, use first argument indexing in maplists/{2..9} 2019-10-12 01:20:42 -06:00
Yu Ding
9b789629c9 Fix some old Rust codes
Done by cargo fix using nightly-2019-10-04 toolchain. Fixed ... to ..=, trait object to dyn trait object
2019-10-09 14:56:50 -07:00
Mark Thom
f898b98b06 copy terms to global variable blackboard, fix attribute_goals//1 2019-10-09 14:11:31 -06:00
Mark Thom
3409db010f fix several issues with goal expansion, crashing after attribute_goals is called 2019-10-08 12:28:23 -06:00
Mark Thom
673fb31ae2 update prolog_parser to v0.8.33 2019-10-06 12:02:47 -06:00
Mark Thom
93d1cd1b09 implement DCGs using the logical expansion of the draft proposal 2019-10-05 00:17:57 -06:00
Mark Thom
3fa168d35b fixes for issues #185 and #181 2019-10-04 20:03:03 -06:00
Mark Thom
1569cac98f correct dcg handling of cuts 2019-10-04 15:41:48 -06:00
Mark Thom
d4f9d18149 print errors with line numbers in GNU style 2019-10-04 15:32:26 -06:00
Mark Thom
caeff99f69 perform singleton variable scans on top level terms only 2019-10-04 10:38:45 -06:00
Mark Thom
0a84f183fe make attribute_goals a nonterminal 2019-10-03 23:29:18 -06:00
Mark Thom
b61ed65208 fix goal expansion in disjunctions, add warnings for singleton variables 2019-10-03 22:13:34 -06:00
Mark Thom
02d1ed237f don't add default index for dynamic predicates unless defined at toplevel 2019-10-02 22:30:00 -06:00
Mark Thom
a2655864c6 update version 2019-10-02 22:13:31 -06:00
Mark Thom
516c66a47d properly handle undefined predicates declared dynamic 2019-10-02 22:01:32 -06:00
Mark Thom
04bc8ec084 print attributes of variables when attribute_goals/2 is not defined 2019-10-02 17:01:03 -06:00
Mark Thom
a623061a1a correct handling of ! in phrase/{2,3}, get rid of extraneous choice points in put_atts/2 and get_atts/2, allow loading of non-module files from the command line and use_module/{2,3} 2019-10-02 15:51:48 -06:00
Mark Thom
ccd3dfb436 properly expand goals in initialization directives 2019-10-02 15:09:34 -06:00
Mark Thom
b12ba338df remove readline_compat_rs reference from README 2019-10-02 11:33:28 -06:00
Mark Thom
239ffb205b expand goals in initialization directives. 2019-10-01 23:25:17 -06:00
Mark Thom
c0ad3231f5 eliminate extraneous choice point in $get_attr 2019-10-01 22:36:46 -06:00
Mark Thom
abc7498a42 add the initialization directive 2019-10-01 16:51:22 -06:00
Mark Thom
1ec831b2e2 limit scope of raw mode on stdout to allow interrupts to work 2019-09-30 14:09:02 -06:00
Mark Thom
b26c5c213e return to toplevel from a long running query after receiving Ctrl-C 2019-09-30 13:27:22 -06:00
Mark Thom
ecb2cc3518 fix improper consolidation of DCG variables 2019-09-30 12:21:53 -06:00
Mark Thom
9df14cf890 add use_module/{1,2} as full fledged predicates 2019-09-30 10:26:29 -06:00
Mark Thom
376b39a4ef support loading of modules from files specified at the command line 2019-09-29 10:16:27 -06:00
Mark Thom
e8bac464d0 devour dangling whitespace before checking for EOF 2019-09-29 10:05:40 -06:00
Mark Thom
5ec4dfedb0 target out_dir in build script 2019-09-27 00:05:19 -06:00
Mark Thom
9a83ccbdbc make *.pl files in src/prolog/lib available from libraries.rs 2019-09-26 23:10:04 -06:00
Mark Thom
2c1c1b7d12 migrate to rustyline, add history support 2019-09-26 11:25:05 -06:00
Mark Thom
529b664bf3 Merge pull request #164 from triska/master
ADDED: library(si) for safe type tests.
2019-09-25 22:52:11 -06:00