# Constraint Processing (#70)

**URL:** <https://www.ruby-forum.com/t/constraint-processing-70/82433>\
**Category:** Ruby\
**Created:** [March 16, 2006, 1:01am UTC](https://www.ruby-forum.com/t/constraint-processing-70/82433 "2006-03-16T01:01:47Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![davidtl](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/35a633/32.png) [@davidtl](https://www.ruby-forum.com/u/davidtl)\
**Post date:** [March 16, 2006, 1:01am UTC](https://www.ruby-forum.com/t/constraint-processing-70/82433/1 "2006-03-16T01:01:47Z")

</div>

Just finish my solution, I run out of time to provide an example …  
define the domain as instance variable.  
define the rule by using block & instance variable.  
define the solution block by using instance variable.  
( all block will exec on “Engine”'s instance\_eval )

class Engine

def go(&solution)  
solve(instance\_variables, &solution)  
end

private  
def method\_missing(name, \*args, &block)  
if name.to\_s =~ /=$/ && block.nil?  
vars(name, \*args)  
elsif args.size == 0 && !block.nil?  
rules(name, &block)  
else  
super  
end  
end

def rules(name, &block)  
self.class.send(:define\_method, name, &block)  
self.class.send(:protected, name)  
end

def vars(name, \*args)  
name = name.to\_s.sub(/=$/, ‘’)  
self.class.class\_eval(“attr\_accessor :#{name}”)  
args = args[0] if args.size == 1 && args[0].respond\_to?(:each)  
instance\_variable\_set("@#{name}", args)  
end

def solve(vars, &solution)  
if (vars.size != 0)  
name = vars.shift  
value = instance\_variable\_get(name)  
value.each { |e|  
instance\_variable\_set(name, e)  
solve(vars.dup, &solution)  
}  
instance\_variable\_set(name, value)  
else  
protected\_methods.each { |method|  
return if !send(method)  
}  
instance\_eval(&solution)  
end  
end

end

if **FILE** == $0  
e = Engine.new  
e.a = 0…4  
e.b = 0…4  
e.c = 0…4  
e.rule1 { @a \< @b }  
e.rule2 { @a + @b == @c }  
e.go { puts “a =\> #@a, b =\> #@b, c =\> #@c” }  
end

**END**
