Skip to content

Commit

Permalink
README update
Browse files Browse the repository at this point in the history
  • Loading branch information
chikamichi committed Aug 28, 2011
1 parent 4fc3b19 commit 7377e3c
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ Ambiguous functions were [defined in John McCarty's 1963 paper](http://www-forma

Typically, the programmer would specify a limited number of alternatives (eg. different values for a variable), so that the program must later choose between them at runtime to find which one(s) are valid predicates to solve the issue at stake. The "issue" is often formalized as a constraint or a set of constraints referencing the variables some alternatives have been provided for. The evaluation may result in the discovery of dead ends, in which case it must "switch" to a previous branching point and start over with a different alternative.

To discover which alternatives groups are valid, a check/discard/switch strategy must be enforced by the program. Most often it will make use of a ambiguous operator, `amb()` which implements this strategy. The most basic version of `amb` would be `amb(x,y)`, which returns, *in an unpredictible way*, either x or y when both are defined, or if only one is defined, whichever is defined. If none is defined, it will terminate the program and complain no solution can be found given these alternatives and constraint(s). Using some recursivity, `amb()` may be used to define arbitrary, complex ambiguous functions. It is quite difficult to implement a good `amb()` operator matching that formal definition. A simpler (yet functional) version has the operator return its first defined argument, then pass over the next defined one in case of a dead-end.
To discover which alternatives groups are valid, a check/discard/switch strategy must be enforced by the program. Most often it will make use of a ambiguous operator, `amb()` which implements this strategy. [Quoting Dorai Sitaram](http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-16.html#node_chap_14), "`amb` takes zero or more expressions, and makes a nondeterministic (or "ambiguous") choice among them, preferring those choices that cause the program to converge meaningfully". The most basic version of `amb` would be `amb(x,y)`, which returns, *in an unpredictible way*, either x or y when both are defined; if only one is defined, whichever is defined; and terminate the program if none is defined. Using some recursivity, `amb()` may be used to define arbitrary, complex ambiguous functions. It is quite difficult to implement a good `amb()` operator matching that formal definition though (for unpredictability is not what computers enjoys doing). A simpler (yet functional) version has the operator return its first defined argument, then pass over the next defined one in case of a dead-end, in a depth-first selection algorithm. It *is* dumb yet it works as expected.

The most common strategy used for implementing `amb()`'s logic (check/discard) is backtracking, which is "a general algorithm for finding all (or some) solutions to some computational problem, that incrementally builds candidates to the solutions, and abandons each partial candidate *c* ("backtracks") as soon as it determines that *c* cannot possibly be completed to a valid solution". It almost always relies on some sort of continuations. It may be turned into backjumping for more efficiency, depending on the problem at stake. Another strategy is reinforcement learning or constraint learning, as used in some AI systems. This library implements simple backtracking only.
Thus the most common strategy used for implementing `amb()`'s logic (check/discard) is chronological backtracking. It almost always relies on some sort of continuations (`call/cc`) and a search algorithm (say, depth-first). The algorithm may be tweaked into a smarter backjumping for more efficiency, depending on the problem at stake. Another strategy is reinforcement learning (aka. constraint learning), as is used in some AI systems. This library implements simple backtracking only though.

More details on all of this under the `doc/`` folder (*pending*).
More details on all of this under the `doc/` folder (*pending*).

## Examples

Expand Down Expand Up @@ -58,14 +58,36 @@ examining x = 3, y = 1
examining x = 3, y = 2
solution: x = 3, y = 2
```
This illustrates the incremental, backtracking pattern. Many more examples under the `examples/` directory.
This illustrates the incremental, backtracking pattern leading to the first valid solution. Many more examples under the `examples/` directory.

## Installation

gem install amb

## Usage

Here's a raw use-case, presenting the required *steps*. For concrete examples, see the `examples/` directory.

First, require the lib:

``` ruby
require 'amb'

# one may either use the Amb module (Amb.choose…) or create a proxy class.
class Ambiguous
include Amb
# opportunity to log & the like here
end

amb = Ambiguous.new
```

Then define your alternatives using `#choose` (aliased as `#choices` or `#alternatives`). It may take arbitrary code (values, proc…).

``` ruby
amb.choose()
```

## TODO

## See also
Expand Down

0 comments on commit 7377e3c

Please sign in to comment.