amb 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +26 -4
- data/lib/amb/amb.rb +6 -3
- data/lib/amb/version.rb +1 -1
- metadata +3 -3
data/README.md
CHANGED
@@ -17,11 +17,11 @@ Ambiguous functions were [defined in John McCarty's 1963 paper](http://www-forma
|
|
17
17
|
|
18
18
|
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.
|
19
19
|
|
20
|
-
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
|
20
|
+
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.
|
21
21
|
|
22
|
-
|
22
|
+
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.
|
23
23
|
|
24
|
-
More details on all of this under the `doc
|
24
|
+
More details on all of this under the `doc/` folder (*pending*).
|
25
25
|
|
26
26
|
## Examples
|
27
27
|
|
@@ -58,7 +58,7 @@ examining x = 3, y = 1
|
|
58
58
|
examining x = 3, y = 2
|
59
59
|
solution: x = 3, y = 2
|
60
60
|
```
|
61
|
-
This illustrates the incremental, backtracking pattern. Many more examples under the `examples/` directory.
|
61
|
+
This illustrates the incremental, backtracking pattern leading to the first valid solution. Many more examples under the `examples/` directory.
|
62
62
|
|
63
63
|
## Installation
|
64
64
|
|
@@ -66,6 +66,28 @@ This illustrates the incremental, backtracking pattern. Many more examples under
|
|
66
66
|
|
67
67
|
## Usage
|
68
68
|
|
69
|
+
Here's a raw use-case, presenting the required *steps*. For concrete examples, see the `examples/` directory.
|
70
|
+
|
71
|
+
First, require the lib:
|
72
|
+
|
73
|
+
``` ruby
|
74
|
+
require 'amb'
|
75
|
+
|
76
|
+
# one may either use the Amb module (Amb.choose…) or create a proxy class.
|
77
|
+
class Ambiguous
|
78
|
+
include Amb
|
79
|
+
# opportunity to log & the like here
|
80
|
+
end
|
81
|
+
|
82
|
+
amb = Ambiguous.new
|
83
|
+
```
|
84
|
+
|
85
|
+
Then define your alternatives using `#choose` (aliased as `#choices` or `#alternatives`). It may take arbitrary code (values, proc…).
|
86
|
+
|
87
|
+
``` ruby
|
88
|
+
amb.choose()
|
89
|
+
```
|
90
|
+
|
69
91
|
## TODO
|
70
92
|
|
71
93
|
## See also
|
data/lib/amb/amb.rb
CHANGED
@@ -77,7 +77,7 @@ module Amb
|
|
77
77
|
base.extend(ClassMethods)
|
78
78
|
end
|
79
79
|
|
80
|
-
# Memoize and return the alternatives continuations.
|
80
|
+
# Memoize and return the alternatives associated continuations.
|
81
81
|
#
|
82
82
|
# @return [Array<Proc, Continuation>]
|
83
83
|
#
|
@@ -102,6 +102,9 @@ module Amb
|
|
102
102
|
# Unconditional failure of a constraint, causing the last choice to be
|
103
103
|
# retried. This is equivalent to saying `assert(false)`.
|
104
104
|
#
|
105
|
+
# Use to force a search for another solution (see examples).
|
106
|
+
# @TODO it'd be better not to have to
|
107
|
+
#
|
105
108
|
def failure
|
106
109
|
back_amb.pop.call
|
107
110
|
end
|
@@ -136,7 +139,7 @@ module Amb
|
|
136
139
|
# Class convenience method to search for the first solution to the
|
137
140
|
# constraints.
|
138
141
|
#
|
139
|
-
def solve(failure_message="No Solution")
|
142
|
+
def solve(failure_message = "No Solution")
|
140
143
|
amb = self.new
|
141
144
|
yield(amb)
|
142
145
|
rescue Amb::ExhaustedError => ex
|
@@ -146,7 +149,7 @@ module Amb
|
|
146
149
|
# Class convenience method to search for all the solutions to the
|
147
150
|
# constraints.
|
148
151
|
#
|
149
|
-
def solve_all(failure_message="No More Solutions")
|
152
|
+
def solve_all(failure_message = "No More Solutions")
|
150
153
|
amb = self.new
|
151
154
|
yield(amb)
|
152
155
|
amb.failure
|
data/lib/amb/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-08-28 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: amb
|
16
|
-
requirement: &
|
16
|
+
requirement: &82652280 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *82652280
|
25
25
|
description: This gem is a compilation of several implementations of the ambiguous
|
26
26
|
function/operator, useful for constraint programming.
|
27
27
|
email: jd@vauguet.fr
|