Hi to you all, dear Oz users,
after about two years of good and pratical work with Oz (I earn real money
from real customers for my work) I would like to share with you some of my
experience and ideas behind the multiparadigmatical use of Oz language.
First level (totally functional).
---------------------------------
The typical problems I must resolve are about jobs tasks an resources.
The need of a interactive gantt rapresentation of the problem and the
availability of both well known tools and human resources led to the
decision to interface an Oz scheduler with a Visual Basic front end.
The result was a good and fast scheduler used by many customers embedded
into a whole ERP application silently running with simple file exchange and
TCP/IP commands.
+ simple to prototype and to have an application up and running
- hard to mantain due to the spreading around many modules of the treatment
of the entyties involved (tasks jobs calendars machines tools ...) seen as
simple records.
- hard to debug code and constraints inside child spaces expecially in not
trivial problems (but when is this an easy task ? ;-)).
Second level (totally object based).
-----------------------------------
Tasks Jobs Resource and so on, were coded completely in Oz redefining a
complete class hyerarchy
TraceObject
Activity
Job
JobMinSpan
JobDueDate
Task
Constraint
Precedence
Resource
ResourceUnary
ResourceDiscrete
Table
Use
Scheduler
SDate
STime
after some figthing with the language idiosyncrasies (I am a Smalltalk
purist ;-)) some prototypes were studied and one of them installed on field.
The front end was simplified to an Excel viewer for different needs (no
interaction, nor bells and whistles) giving origin to another different
product.
+ tracing and debugging was simpler due to the indirection of all nessages
inside the root class TraceObject
- the price was in performance (but not a concern when debugging)
+ maintenance and extentions were definitively simpler
third level (constraint service).
---------------------------------
Thanks to the enlightment that Christian Schulte gave me with his book
"Programming Constraint Services" I realized that there should be another
way to think about Oz and its capabilities.
The point was to let the language work in the field where it "does it
better" and stop fighting the religious war trying to coerce the language
onto the problem.
Wouldn't be nice if I only could express the problem with my XXX preferred
language and let the Oz Constraint Service solve it ?.
Yes, the starting point was to define a low level of communication where
Spaces as first class entities are used.
I'll try to explain in the reverse sense starting with the hithest level of
the model and in VisualBasic as modelling language:
'define a container for the problem
Set sched = New Scheduler
'define the Oz Constraint Server as UserControl
Set sched.cspServer = OzServerInterface1
'define the problem
sched.addJob "ja"
sched.addJob "jb"
sched.addResource "r1"
sched.addResource "r2"
sched.addTask "t1a", "ja", "r1", 7 'id,job,resource,duration
sched.addTask "t2a", "ja", "r2", 4
sched.addTask "t1b", "jb", "r1", 9
sched.addTask "t2b", "jb", "r2", 6
sched.addTask "t3b", "jb", "r1", 4
'define the constraints
addJobsConstraints
addResourcesConstraints
'get the solution
schedule
Public Sub addJobsConstraints()
'declare the sequence constraint
Dim j As Job
For Each j In jobs
cspServer.addConstraint j.id, j.constraint
Next
End Sub
Public Sub addResourcesConstraints()
'declare the serialize propagator
cspServer.addConstraint serialize
End Sub
Public Sub schedule()
'CSP stuff communicating with the Oz Server
cspServer.declareVariables
cspServer.applyConstraints
cspServer.solve
End Sub
here you can see the traffic generated by the fragment above
===================================================================
ozengine execute.ozf --commands=Commands.ozf --interface=socket --port=8008
'OZ_CSP started ver:0.1'
' {CurCSP declareVars(10 0 100 0 $)}'
'true'
' {CurCSP inject(proc{$ R} R.fd.1.v + 7 =: R.fd.2.v end $)}'
'true'
' {CurCSP inject(proc{$ R} R.fd.3.v + 4 =: R.fd.4.v end $)}'
'true'
' {CurCSP inject(proc{$ R} R.fd.5.v + 9 =: R.fd.6.v end $)}'
'true'
' {CurCSP inject(proc{$ R} R.fd.7.v + 6 =: R.fd.8.v end $)}'
'true'
' {CurCSP inject(proc{$ R} R.fd.9.v + 4 =: R.fd.10.v end $)}'
'true'
' {CurCSP inject(proc{$ R} R.fd.2.v =<: R.fd.3.v end $)}'
'true'
' {CurCSP inject(proc{$ R} R.fd.8.v =<: R.fd.9.v R.fd.6.v =<: R.fd.7.v end
$)}'
'true'
' {CurCSP inject(proc{$ R} {Serialize R [ [1 5 9 ] [3 7 ]] [ [1 7] [3 4] [5
9] [7 6] [9 4]]} end $)}'
'true'
' {CurCSP inject(proc{$ R} {CurCSP distributor(naive R.fd)} end $)}'
'true'
' {CurCSP searchFirst($)}'
'true'
' {CurCSP getFDvars($)}'
'fd(0 7 7 11 7 16 16 22 22 26)'
=========================================================================
as you noticed the hight level entities (tasks, jobs...) are not visible, in
fact only the Finite Domain variables are treated by the Oz level.
The method declareVars(NFDVar MinDom MaxDom NBoolVar) simply declares all
the FD variables and boolean variables involved.
Every variable is referenced positionally and VB translates the symbolic
names into the proper indexes.
every constraint is injected into the current Space and tested for failure
letting the application to detect an overconstraining situation.
every task is defined in VB as:
Set t = New Task
Set t.fdStart = cspServer.newFDVar()
Set t.fdEnd = cspServer.newFDVar()
where every FDVar is defined in VB as:
'FDVar Class
Public index As Long
Public name As String
Public domain As Variant 'empty|long|array
and updated at the end of the work with the getFDVars($) method.
All this is only a prototype but seems to be very interesting, where the
main advantage is the horizontal division of the workload into two levels:
a CSP level modelled by a CSP expert (domains, constraints, propagators,
distribution, search)
an application level modelled by an application expert in the preferred
language (VisualBasic, Python, Smalltalk...)
Let me know your opinions and suggestions,
Adriano
-----
Adriano Volpones
Ars Computandi s.c.r.l.
via G.Donizetti, 20
24040 Canonica D'Adda - BERGAMO - ITALY
cell. +39 347 8344988
adriano.volpones@arscomputandi.com http://www.arscomputandi.com
-
Please send submissions to users@mozart-oz.org
and administriva mail to users-request@mozart-oz.org.
The Mozart Oz web site is at http://www.mozart-oz.org/.
Please send bug reports to bugs@mozart-oz.org.