amb 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README.md +26 -4
  2. data/lib/amb/amb.rb +6 -3
  3. data/lib/amb/version.rb +1 -1
  4. 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, 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.
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
- 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.
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/`` folder (*pending*).
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
@@ -1,6 +1,6 @@
1
1
  module Amb
2
2
  MAJOR = 0
3
3
  MINOR = 0
4
- PATCH = 2
4
+ PATCH = 3
5
5
  VERSION = [MAJOR, MINOR, PATCH].join('.')
6
6
  end
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.2
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: &73260010 !ruby/object:Gem::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: *73260010
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