Constraints

 Back home

 

ActConstraint subclass: #ActEquals
	instanceVariableNames: 'x y'
	classVariableNames: ''
	poolDictionaries: ''!

!ActEquals class methods !

x: var1 y: var2
	^super new x: var1 y: var2.

!ActEquals methods !

x: var1 y: var2
	x := var1 . y := var2.
	self post; init.

init
	| m s |
	m := x min max: y min.
	s := x max min: y max.
	x min: m; max: s.
	y min: m; max: s

post
	x when: #min send: #xmin to: self.
	x when: #max send: #xmax to: self.
	y when: #min send: #ymin to: self.
	y when: #max send: #ymax to: self

xmax
	y max: x max

xmin
	y min: x min

ymax
	x max: y max

ymin
	x min: y min

======================

ActConstraint subclass: #ActAdd
	instanceVariableNames: 'x y r'
	classVariableNames: ''
	poolDictionaries: ''    !

!ActAdd class methods !

x: var1 y: var2
	^super new x: var1 y: var2

!ActAdd methods !

x: aVar1 y: aVar2
	x := aVar1 
	y := aVar2.
	r := ConstrainedVariable from: (x min + y min) to: (x max + y max).
	self post

post
	x when: #min send: #xmin to: self.
	x when: #max send: #xmax to: self.
	y when: #min send: #ymin to: self.
	y when: #max send: #ymax to: self.
	r when: #min send: #rmin to: self.
	r when: #max send: #rmax to: self.

rmax
	x max: (r max - y min).
	y max: (r max - x min).!

rmin
	x min: r min - y max.
	y min: r min - x max!

xmax
	r max: x max + y max.
	y min: r min - x max

xmin
	y max: r max - x min.
	r min: y min + x min

ymax
	r max: x max + y max.
	x min: r min - y max

ymin
	x max: r max - y min.
	r min: x min + y min

=========

ActConstraint subclass: #ActTimes
  instanceVariableNames: 'x y r'
  classVariableNames: ''
  poolDictionaries: ''  !

!ActTimes class methods ! !

x: var1 y: anInteger
	^super new x: var1 y: anInteger

!ActTimes methods !

x: aVar1 y: anInteger 
	x := var1. y := anInteger.
	anInteger >= 0
		ifTrue: [r := ConstrainedVariable from: anInteger * x min to: anInteger * x max]
		ifFalse: [r := ConstrainedVariable from: anInteger * x max to: anInteger * x min].
	self post.

post
	x when: #min send: #xmin to: self.
	x when: #max send: #xmax to: self.
	r when: #min send: #rmin to: self.
	r when: #max send: #rmax to: self.

rmax
	y >= 0
		ifTrue: [x max: ( r max / y) floor]
		ifFalse: [x min:  (r max / y) ceiling ]

rmin
	y >= 0
		ifTrue: [x min:  (r min / y) ceiling]
		ifFalse: [x max: ( r min / y) floor]

xmax
	y >= 0
		ifTrue: [r max: y * x max]
		ifFalse: [r min: y * x min]

xmin
	y >= 0
		ifTrue: [r min: y * x min]
		ifFalse: [r max: y * x min]

=================
Example

The simple example is to test the code, and show how some partial solving can be achieved. It defines 
the domains of the variables, and sets the only constraint :
x + 3y + 4z = 2t +c.

ConstrainedVariable class>>example
	"ConstrainedVariable example"

	| x y z t c |
	x := ConstrainedVariable from: 0 to: 3. x name: 'x'.
	y := ConstrainedVariable from: 0 to: 1. y name: 'y'.
	z := ConstrainedVariable from: 2 to: 5. z name: 'z'.
	t := ConstrainedVariable from: 0 to: 3. t name: 't'.
	c :=  ConstrainedVariable on: #(5). c name: 'c'.
	((x + (y * 3 ))+ (z * 4) )@=( (t * 2)+ c).

	x printOn: Transcript.
	y printOn: Transcript.
	z printOn: Transcript.
	t printOn: Transcript.
	Transcript cr.