1: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3: % %
4: % This file has been generated by raw2tex from a .raw file %
5: % raw2tex (flex) by Denys Duchier, April 1996 %
6: % DON'T EDIT THIS FILE ! %
7: % %
8: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9: %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10: \documentclass{tlp}
11:
12: \sloppy
13:
14: \usepackage{aopmath}
15: \usepackage[latin1]{inputenc}
16: \usepackage{psfig}
17: \usepackage{latexsym}
18: \usepackage{oz2tex}
19:
20: \newcommand{\pivot}[1]{\mathbin{\, {#1} \,}}
21: \newcommand{\Pivot}[1]{\mathbin{\; {#1} \;}}
22: \let\from=\leftarrow
23:
24: \newcommand{\nt}[1]{$\langle\textsf{#1}\rangle$}
25:
26: \bibliographystyle{tlp}
27: \begin{document}
28:
29: % \advance\topmargin by -1cm
30: % \textwidth 14cm
31: % \textheight 22.5cm
32: % \advance\oddsidemargin by -1cm
33: % \advance\evensidemargin by -1cm
34:
35: \title[Logic programming in Oz]{Logic programming in the context of\\
36: multiparadigm programming:\\
37: the Oz experience \footnote{
38: This article is a much-extended version of the tutorial talk
39: ``Logic Programming in Oz with Mozart''
40: given at the International Conference on Logic Programming,
41: Las Cruces, New Mexico, Nov.~1999.
42: Some knowledge of traditional logic programming
43: (with Prolog or concurrent logic languages) is assumed.}
44: }
45:
46: \author[P. Van Roy et al.]
47: {PETER VAN ROY\\
48: Universit\'{e} catholique de Louvain,
49: B-1348 Louvain-la-Neuve, Belgium
50: \and
51: PER BRAND\\
52: Swedish Institute of Computer Science, S-164 28 Kista, Sweden
53: \and
54: DENYS DUCHIER\\
55: Universit\"at des Saarlandes, D-66123 Saarbr\"ucken, Germany
56: \and
57: SEIF HARIDI\\
58: Royal Institute of Technology (KTH), S-164 28 Kista, Sweden
59: \and
60: MARTIN HENZ\\
61: National University of Singapore, Singapore 117543
62: \and
63: CHRISTIAN SCHULTE\\
64: Royal Institute of Technology (KTH), S-164 28 Kista, Sweden}
65:
66: % Email: {\tt pvr@info.ucl.ac.be}.} ,\
67: % Email: {\tt perbrand@sics.se}.} ,\
68: % Email: {\tt Denys.Duchier@ps.uni-sb.de}.} ,\\
69: % Email: {\tt seif@imit.kth.se}.} ,\
70: % Email: {\tt henz@comp.nus.edu.sg}.} ,\ \ and
71: % Email: {\tt schulte@imit.kth.se}.}
72:
73: \maketitle
74: \label{firstpage}
75:
76: \begin{abstract}
77: Oz is a multiparadigm language that supports logic programming as one
78: of its major paradigms. A multiparadigm language is designed to
79: support different programming paradigms (logic, functional,
80: constraint, object-oriented, sequential, concurrent, etc.) with equal
81: ease. This article has two goals: to give a tutorial of logic
82: programming in Oz and to show how logic programming fits naturally
83: into the wider context of multiparadigm programming.
84: Our experience shows that there are two classes of problems, which we
85: call {\em algorithmic} and {\em search} problems, for which logic
86: programming can help formulate practical solutions.
87: {\em Algorithmic} problems have known efficient algorithms.
88: {\em Search} problems do not have
89: known efficient algorithms but can be solved with search.
90: The Oz support for logic programming targets these two
91: problem classes specifically, using the concepts needed for each.
92: This is in contrast to the Prolog approach, which targets
93: both classes with one set of concepts, which results in
94: less than optimal support for each class.
95: We give examples
96: that can be run interactively on the Mozart system,
97: which implements Oz.
98: To explain the essential difference between algorithmic and
99: search programs, we define the Oz execution model.
100: This model subsumes both concurrent
101: logic programming (committed-choice-style) and search-based logic
102: programming (Prolog-style). Furthermore, as consequences of
103: its multiparadigm nature, the model supports new abilities
104: such as first-class top levels, deep guards, active objects, and
105: sophisticated control of the search process. Instead of Horn clause
106: syntax, Oz has a simple, fully compositional, higher-order syntax that
107: accommodates the abilities of the language.
108: We give a brief
109: history of Oz that traces the development of its main ideas
110: and we summarize the lessons learned from this work.
111: Finally, we give many entry points into the Oz literature.
112: \end{abstract}
113:
114: \section{Introduction}
115:
116: In our experience,
117: logic programming can help give
118: practical solutions to many different problems.
119: We have found that all these problems
120: can be divided into two classes,
121: each of which uses a totally different approach:
122: \begin{itemize}
123: \item {\bf Algorithmic problems}.
124: These are problems for which efficient algorithms are known.
125: This includes parsing, rule-based expert systems,
126: and transformations of complex symbolic data structures.
127: For such problems,
128: a logical specification of the algorithm
129: is sometimes simpler than an imperative specification.
130: In that case, {\em deterministic logic programming}
131: or {\em concurrent logic programming} may be natural ways
132: to express it.
133: Logical specifications are not always simpler.
134: Sometimes an imperative specification is better,
135: e.g., for problems in which
136: state updating is frequent.
137: Many graph algorithms are of the latter type.
138:
139: \item {\bf Search problems}.
140: These are problems for which efficient algorithms are not known.
141: This may be either because such algorithms are
142: not possible in principle
143: or because such algorithms have not been made explicit.
144: We cite, e.g., NP-complete problems~\cite{Garey.79}
145: or problems with complex specifications
146: whose algorithms are difficult for this reason.
147: Some examples of search problems are
148: optimization problems (planning, scheduling, configuration),
149: natural language parsing, and theorem proving.
150: These kinds of problems can be solved by doing search, i.e.,
151: with {\em nondeterministic logic programming}.
152: But search is a dangerous tool.
153: If used naively,
154: it does not scale up to real applications.
155: This is because the size of the search space grows
156: exponentially with the problem size.
157: For a real application, all possible effort must be
158: made to reduce the need for search: use strong (global) constraints,
159: concurrency for cooperative constraints,
160: heuristics for the search tree, etc.~\cite{fdtutorial}.
161: For problems with complex specifications,
162: using sufficiently strong constraints
163: sometimes results in a polynomial-time algorithm~\cite{CP-NL}.
164: \end{itemize}
165: For this paper, we consider
166: {\em logic programming} as programming with
167: executable specifications written in a simple logic
168: such as first-order predicate calculus.
169: The Oz support for logic programming is targeted
170: specifically towards the two
171: classes of algorithmic problems and search problems.
172: The first part of this article
173: (Sections~\ref{detlp}--\ref{moresearch})
174: shows how to write logic programs
175: in Oz for these problems.
176: Section~\ref{detlp} introduces deterministic logic programming,
177: which targets algorithmic problems.
178: It is the most simple and direct way of doing logic programming in Oz.
179: Section~\ref{nondetlp} shows how to do
180: nondeterministic logic programming in the Prolog style.
181: This targets neither algorithmic nor search problems,
182: and is therefore only of pedagogical interest.
183: Section~\ref{conclp} shows how to do concurrent logic
184: programming in the classical tradition.
185: This targets more algorithmic problems.
186: Section~\ref{state} extends Section~\ref{conclp}
187: with state.
188: In our experience, state
189: is essential for practical concurrent logic programming.
190: Section~\ref{moresearch}
191: expands on Section~\ref{nondetlp} to show how search
192: can be made practical.
193:
194: The second part of this article
195: (Sections~\ref{executionmodel}--\ref{lessons})
196: focuses on the essential difference between the
197: techniques used to solve
198: algorithmic and search problems.
199: This leads to the wider context
200: of {\em multiparadigm} programming.
201: Section~\ref{executionmodel} introduces the Oz execution model,
202: which has a strict functional core and
203: extensions for concurrency, lazy evaluation,
204: exception handling, security, state, and search.
205: The section explains how these extensions can be
206: used in different combinations
207: to provide different programming paradigms.
208: In particular, Section~\ref{compspaces} explains the abstraction
209: of {\em computation spaces},
210: which is the main tool for doing search in Oz.
211: Spaces make possible a deep synthesis of concurrent and
212: constraint logic programming.
213: Section~\ref{related} gives an overview of other
214: research in multiparadigm programming
215: and a short history of Oz.
216: Finally,
217: Section~\ref{lessons} summarizes the lessons we have learned in
218: the Oz project on how to do practical logic programming
219: and multiparadigm programming.
220:
221: This article gives an informal (yet precise)
222: introduction targeted towards Prolog programmers.
223: A more complete presentation
224: of logic programming in Oz and
225: its relationship to other programming concepts
226: is given in the textbook~\cite{book}.
227:
228: \section{Deterministic logic programming}
229: \label{detlp}
230:
231: We call {\em deterministic} logic programming the case
232: when the algorithm's control
233: flow is completely known and specified by the programmer.
234: No search is needed.
235: This is perfectly adapted to sequential algorithmic problems.
236: For example, a deterministic naive reverse can be
237: written as follows in Oz:
238: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{declare}\OzEol
239: \OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{Append\OzSpace{1}Xs\OzSpace{1}Ys\OzSpace{1}Zs\OzChar\}\OzEol
240: \OzSpace{6}\OzKeyword{case}\OzSpace{1}Xs\OzEol
241: \OzSpace{6}\OzKeyword{of}\OzSpace{1}nil\OzSpace{1}\OzKeyword{then}\OzSpace{1}Zs=Ys\OzEol
242: \OzSpace{6}[]\OzSpace{1}X|Xr\OzSpace{1}\OzKeyword{then}\OzSpace{1}Zr\OzSpace{1}\OzKeyword{in}\OzEol
243: \OzSpace{9}Zs=X|Zr\OzSpace{1}\OzChar\{Append\OzSpace{1}Xr\OzSpace{1}Ys\OzSpace{1}Zr\OzChar\}\OzEol
244: \OzSpace{6}\OzKeyword{end}\OzEol
245: \OzSpace{3}\OzKeyword{end}\OzEol
246: \OzEol
247: \OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{NRev\OzSpace{1}Xs\OzSpace{1}Ys\OzChar\}\OzEol
248: \OzSpace{6}\OzKeyword{case}\OzSpace{1}Xs\OzEol
249: \OzSpace{6}\OzKeyword{of}\OzSpace{1}nil\OzSpace{1}\OzKeyword{then}\OzSpace{1}Ys=nil\OzEol
250: \OzSpace{6}[]\OzSpace{1}X|Xr\OzSpace{1}\OzKeyword{then}\OzSpace{1}R\OzSpace{1}\OzKeyword{in}\OzEol
251: \OzSpace{9}\OzChar\{NRev\OzSpace{1}Xr\OzSpace{1}R\OzChar\}\OzEol
252: \OzSpace{9}\OzChar\{Append\OzSpace{1}R\OzSpace{1}[X]\OzSpace{1}Ys\OzChar\}\OzEol
253: \OzSpace{6}\OzKeyword{end}\OzEol
254: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
255: This syntax should be vaguely familiar
256: to people with some knowledge of Prolog and functional
257: programming~\cite{artofprolog,maierwarren,haskellbook,caml}.
258: We explain it briefly, pointing out where it differs from Prolog.
259: All capitalized identifiers refer to logic variables
260: in a constraint store.\footnote{Including
261: \OzInline{Append} and \OzInline{NRev}, which are bound to procedure values
262: (lexically-scoped closures).}
263: \OzInline{Append} and \OzInline{NRev} are procedures whose arguments are passed
264: by unification, as in Prolog.
265: The \OzInline{\OzKeyword{declare}} declares new global identifiers,
266: \OzInline{Append} and \OzInline{NRev},
267: which are bound to the newly-created procedure values.
268: This means that the order of the declarations does not matter.
269: All local variables must be declared within a scope, e.g.,
270: ``\OzInline{Zr\OzSpace{1}\OzKeyword{in}}'' and ``\OzInline{R\OzSpace{1}\OzKeyword{in}}'' declare \OzInline{Zr} and \OzInline{R}
271: with scopes to the next enclosing \OzInline{\OzKeyword{end}} keyword.
272: A list is either the atom \OzInline{nil} or a pair
273: of an element \OzInline{X} and a list \OzInline{Xr}, written \OzInline{X|Xr}.
274: The \OzInline{[]} is not an empty list,
275: but separates clauses in a \OzInline{\OzKeyword{case}} statement
276: (similar to a guarded command, except that \OzInline{\OzKeyword{case}} is sequential).
277:
278: We explain briefly the semantics of the naive reverse
279: to highlight the relationship to logic programming.
280: The constraint store consists of equality constraints over
281: rational trees, similar to what is provided by many modern Prolog systems.
282: Statements are executed sequentially.
283: There are two basic operations on the store,
284: ask and tell~\cite{SaraswatBook}:
285: \begin{itemize}
286: \item The tell operation (e.g., \OzInline{Ys=nil})
287: adds a constraint; it performs unification.
288: The tell is an {\em incremental tell}; if the constraint
289: is inconsistent with the store then only a consistent
290: part is added and an exception is raised
291: (see, e.g.,~\cite{opm} for a formal definition).
292: \item The ask operation is the \OzInline{\OzKeyword{case}} statement
293: (e.g., \OzInline{\OzKeyword{case}\OzSpace{1}Xs\OzSpace{1}\OzKeyword{of}\OzSpace{1}X|Xr\OzSpace{1}\OzKeyword{then}\OzSpace{1}...\OzSpace{1}\OzKeyword{else}\OzSpace{1}...\OzSpace{1}\OzKeyword{end}}).
294: It waits until the store contains enough information
295: to decide whether the pattern is matched (entailment)
296: or can never be matched (disentailment).
297: \end{itemize}
298: The above example can be written in a functional syntax.
299: We find that a functional syntax
300: often greatly improves the readability of programs.
301: It is especially useful when it follows the data flow,
302: i.e., the input and output arguments.
303: In Oz, the definition of \OzInline{NRev} in functional syntax
304: is as follows:
305: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{declare}\OzEol
306: \OzSpace{3}\OzKeyword{fun}\OzSpace{1}\OzChar\{Append\OzSpace{1}Xs\OzSpace{1}Ys\OzChar\}\OzEol
307: \OzSpace{6}\OzKeyword{case}\OzSpace{1}Xs\OzSpace{1}\OzKeyword{of}\OzSpace{1}nil\OzSpace{1}\OzKeyword{then}\OzSpace{1}Ys\OzEol
308: \OzSpace{6}[]\OzSpace{1}X|Xr\OzSpace{1}\OzKeyword{then}\OzSpace{1}X|\OzChar\{Append\OzSpace{1}Xr\OzSpace{1}Ys\OzChar\}\OzSpace{1}\OzKeyword{end}\OzEol
309: \OzSpace{3}\OzKeyword{end}\OzEol
310: \OzEol
311: \OzSpace{3}\OzKeyword{fun}\OzSpace{1}\OzChar\{NRev\OzSpace{1}Xs\OzChar\}\OzEol
312: \OzSpace{6}\OzKeyword{case}\OzSpace{1}Xs\OzSpace{1}\OzKeyword{of}\OzSpace{1}nil\OzSpace{1}\OzKeyword{then}\OzSpace{1}nil\OzEol
313: \OzSpace{6}[]\OzSpace{1}X|Xr\OzSpace{1}\OzKeyword{then}\OzSpace{1}\OzChar\{Append\OzSpace{1}\OzChar\{NRev\OzSpace{1}Xr\OzChar\}\OzSpace{1}[X]\OzChar\}\OzSpace{1}\OzKeyword{end}\OzEol
314: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
315: This is just syntactic sugar for the procedural definition.
316: In Oz, a function is just a shorter way of writing
317: a procedure where the procedure's last argument
318: is the function's output.
319: The statement \OzInline{Ys=\OzChar\{NRev\OzSpace{1}Xs\OzChar\}} has identical semantics
320: to the procedure call \OzInline{\OzChar\{NRev\OzSpace{1}Xs\OzSpace{1}Ys\OzChar\}}.
321:
322: From the semantics outlined above,
323: it follows that \OzInline{Append} and \OzInline{NRev} do not search.
324: If there is not enough information to continue,
325: then the computation will simply block.
326: For example, take these two calls:
327: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{declare}\OzSpace{1}X\OzSpace{1}Y\OzSpace{1}A\OzSpace{1}B\OzSpace{1}\OzKeyword{in}\OzEol
328: \OzSpace{3}\OzChar\{Append\OzSpace{1}[1]\OzSpace{1}X\OzSpace{1}Y\OzChar\}\OzEol
329: \OzSpace{3}\OzChar\{Append\OzSpace{1}A\OzSpace{1}[2]\OzSpace{1}B\OzChar\}\end{oz2texdisplay}
330: (The \OzInline{\OzKeyword{declare}} ... \OzInline{\OzKeyword{in}} introduces new variables.)
331: The first call, \OzInline{\OzChar\{Append\OzSpace{1}[1]\OzSpace{1}X\OzSpace{1}Y\OzChar\}}, will run to completion
332: since \OzInline{Append} does not need the value of its second argument.
333: The result is the binding of \OzInline{Y} to \OzInline{1|X}.
334: The second call, \OzInline{\OzChar\{Append\OzSpace{1}A\OzSpace{1}[2]\OzSpace{1}B\OzChar\}}, will suspend the thread
335: it is executing in.
336: This is because the \OzInline{\OzKeyword{case}} statement does not have enough
337: information to decide what \OzInline{A} is.
338: No binding is done.
339: If another thread binds \OzInline{A}, then execution will continue.
340: % In practice, programming errors often result in suspensions;
341: % when this happens the Oz Debugger is a useful tool
342: % to find out what is suspending~\cite{debugger}.
343:
344: This is how Oz supports deterministic logic programming.
345: It is purely declarative logic programming
346: with an operational semantics that
347: is fully specified and deterministic.
348: Programs can be translated
349: in a straightforward way
350: to a Horn clause syntax.
351: However, deductions are not performed by resolution.
352: The execution can be seen as functional programming
353: with logic variables and dynamic typing,
354: carefully designed to have a logical semantics.
355: Resolution was originally designed as an inference
356: rule for automatic theorem provers~\cite{robinson}; it is not
357: a necessary part of a logic programming language.
358:
359: Note that there are higher-order procedures
360: as in a functional language,
361: but no higher-order logic programming,
362: i.e., no logic programming based on a higher-order logic.
363: Higher-order procedures are useful within first-order
364: logic programming as a tool to structure programs and build abstractions.
365:
366: We find that adding logic variables
367: to functional programming is
368: an important extension for three reasons.
369: First, it allows to do deterministic logic programming
370: in a straightforward way.
371: Second, it increases expressiveness by
372: allowing powerful programming techniques based
373: on incomplete data structures,
374: such as tail-recursive append and
375: difference lists~\cite{difflist,artofprolog}.
376: The third reason is perhaps the most important:
377: adding concurrency to this execution model gives
378: a useful form of concurrent programming called
379: {\em declarative concurrency} (see Section~\ref{kernellang}).
380:
381: \section{Nondeterministic logic programming}
382: \label{nondetlp}
383:
384: We call {\em nondeterministic} logic programming the
385: situation when {\em search} is used to provide completeness.
386: Using search allows finding solutions
387: when no other algorithm is known.\footnote{To be
388: precise, search is a general technique that works for any problem
389: by giving just the problem specification,
390: but it can be impractical because it does brute force exploration
391: of a potentially large space of candidate solutions.
392: Search can be made more efficient by incorporating
393: problem-specific knowledge, e.g., games can be programmed
394: using alpha-beta search.}
395: Oz provides the \OzInline{\OzKeyword{choice}} statement
396: as a simple way to introduce search.
397: The \OzInline{\OzKeyword{choice}} statement creates
398: a choice point for its alternatives.
399:
400: The \OzInline{\OzKeyword{choice}} statement allows
401: to do Prolog-style generative execution.
402: However, this style of programming
403: does not scale up to real-world search problems.\footnote{For
404: problems with a small search space,
405: they may be sufficient.
406: For example, a practical diagnostics generator for the VLSI-BAM
407: microprocessor was written in Prolog~\cite{holmerjlp,agdi}.}
408: In our opinion,
409: its primary value is pedagogical and exploratory.
410: That is, it can be used on small examples to explore
411: and understand a problem's structure.
412: With this understanding, a more efficient
413: algorithm can often be designed.
414: When used naively,
415: search will not work on large examples
416: due to search space explosion.
417:
418: Search is a fundamental part of constraint programming.
419: Many techniques have been devised there
420: to reduce greatly the size of the search space.
421: Section~\ref{moresearch} gives a simple example
422: to illustrate some of these techniques.
423:
424: Here is a nondeterministic naive reverse with \OzInline{\OzKeyword{choice}}:
425: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{Append\OzSpace{1}Xs\OzSpace{1}Ys\OzSpace{1}Zs\OzChar\}\OzEol
426: \OzSpace{6}\OzKeyword{choice}\OzSpace{8}Xs=nil\OzSpace{2}Zs=Ys\OzEol
427: \OzSpace{6}[]\OzSpace{1}X\OzSpace{1}Xr\OzSpace{1}Zr\OzSpace{1}\OzKeyword{in}\OzSpace{1}Xs=X|Xr\OzSpace{1}Zs=X|Zr\OzSpace{1}\OzChar\{Append\OzSpace{1}Xr\OzSpace{1}Ys\OzSpace{1}Zr\OzChar\}\OzEol
428: \OzSpace{6}\OzKeyword{end}\OzEol
429: \OzSpace{3}\OzKeyword{end}\OzEol
430: \OzEol
431: \OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{NRev\OzSpace{1}Xs\OzSpace{1}Ys\OzChar\}\OzEol
432: \OzSpace{6}\OzKeyword{choice}\OzSpace{5}Xs=nil\OzSpace{2}Ys=nil\OzEol
433: \OzSpace{6}[]\OzSpace{1}X\OzSpace{1}Xr\OzSpace{1}\OzKeyword{in}\OzSpace{1}Xs=X|Xr\OzSpace{1}\OzChar\{Append\OzSpace{1}\OzChar\{NRev\OzSpace{1}Xr\OzChar\}\OzSpace{1}[X]\OzSpace{1}Ys\OzChar\}\OzEol
434: \OzSpace{6}\OzKeyword{end}\OzEol
435: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
436: (In this and all further examples, we leave out
437: the \OzInline{\OzKeyword{declare}} for brevity.)
438: Because this example does not use higher-order programming,
439: there is a direct translation to the Horn clause syntax of Prolog:
440: \begin{verbatim}
441: append(Xs, Ys, Zs) :- Xs=nil, Zs=Ys.
442: append(Xs, Ys, Zs) :- Xs=[X|Xr], Zs=[X|Zr], append(Xr, Ys, Zr).
443:
444: nrev(Xs, Ys) :- Xs=nil, Ys=nil.
445: nrev(Xs, Ys) :- Xs=[X|Xr], nrev(Xr, Yr), append(Yr, [X], Ys).
446: \end{verbatim}
447: If the Oz program is run with depth-first search,
448: its semantics will be identical to the Prolog version.
449:
450: \subsection*{Controlling search}
451:
452: The program for nondeterministic naive reverse
453: can be called in many ways, e.g.,
454: by lazy depth-first search (similar to a Prolog top level) \footnote{Lazy
455: search is different from lazy evaluation in that
456: the program must explicitly request the next solution
457: (see Section~\ref{executionmodel}).},
458: eager search,
459: or interactive search (with the Explorer tool~\cite{explorer,mildversion}).
460: All of these search abilities are programmed
461: in Oz using the notion of computation space
462: (see Section~\ref{executionmodel}).
463: Often the programmer will never use
464: spaces directly (although he or she can), but will
465: use one of the many predefined search
466: abstractions provided in the \OzInline{Search} module
467: (see Section~\ref{simplesearch}).
468:
469: As a first example, let us introduce an abstraction,
470: called {\em search object},
471: that is similar to a Prolog top level.
472: It does depth-first search and
473: can be queried to obtain successive solutions.
474: Three steps are needed to use it: \footnote{For clarity,
475: we leave out syntactic short-cuts.
476: For example, calculating and displaying the next solution
477: can be written as \OzInline{\OzChar\{Browse\OzSpace{1}\OzChar\{E\OzSpace{1}next(\OzChar\$)\OzChar\}\OzChar\}}.}
478: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{declare}\OzSpace{1}P\OzSpace{1}E\OzSpace{1}\OzKeyword{in}\OzEol
479: \OzSpace{3}\OzEolComment{\OzSpace{1}1.\OzSpace{1}Define\OzSpace{1}a\OzSpace{1}new\OzSpace{1}search\OzSpace{1}query:}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{P\OzSpace{1}S\OzChar\}\OzSpace{1}X\OzSpace{1}Y\OzSpace{1}\OzKeyword{in}\OzSpace{1}\OzChar\{Append\OzSpace{1}X\OzSpace{1}Y\OzSpace{1}[1\OzSpace{1}2\OzSpace{1}3\OzSpace{1}4\OzSpace{1}5]\OzChar\}\OzSpace{1}S=sol(X\OzSpace{1}Y)\OzSpace{1}\OzKeyword{end}\OzEol
480: \OzEol
481: \OzSpace{3}\OzEolComment{\OzSpace{1}2.\OzSpace{1}Set\OzSpace{1}up\OzSpace{1}a\OzSpace{1}new\OzSpace{1}search\OzSpace{1}engine:}\OzSpace{3}E=\OzChar\{New\OzSpace{1}Search.object\OzSpace{1}script(P)\OzChar\}\OzEol
482: \OzEol
483: \OzSpace{3}\OzEolComment{\OzSpace{1}3.\OzSpace{1}Calculate\OzSpace{1}and\OzSpace{1}display\OzSpace{1}the\OzSpace{1}first\OzSpace{1}solution:}\OzSpace{3}\OzEolComment{\OzSpace{4}(and\OzSpace{1}others,\OzSpace{1}when\OzSpace{1}repeated)}\OzSpace{3}\OzKeyword{local}\OzSpace{1}X\OzSpace{1}\OzKeyword{in}\OzSpace{1}\OzChar\{E\OzSpace{1}next(X)\OzChar\}\OzSpace{1}\OzChar\{Browse\OzSpace{1}X\OzChar\}\OzSpace{1}\OzKeyword{end}\end{oz2texdisplay}
484: Let us explain each of these steps:
485: \begin{enumerate}
486: \item The procedure \OzInline{P} defines the query
487: and returns the solution \OzInline{S} in its single argument.
488: Because Oz is a higher-order language,
489: the query can be any statement.
490: In this example, the solution has two parts, \OzInline{X} and \OzInline{Y}.
491: We pair them together in the tuple \OzInline{sol(X\OzSpace{1}Y)}.
492:
493: \item The search object is an instance of the class \OzInline{Search.object}.
494: The object is created with \OzInline{New} and initialized with
495: the message \OzInline{script(P)}.
496:
497: \item The object invocation \OzInline{\OzChar\{E\OzSpace{1}next(X)\OzChar\}} finds
498: the next solution of the query \OzInline{P}.
499: If there is a solution, then \OzInline{X} is bound to a list
500: containing it as single element.
501: If there are no more solutions, then \OzInline{X} is bound to \OzInline{nil}.
502: \OzInline{Browse} is a tool provided by the system to display data structures.
503: \end{enumerate}
504: % This example introduces an important syntactic short-cut:
505: % the use of ``\?$?'' (dollar) as a nesting marker.
506: % The dollar indicates the part of a nested expression
507: % that is passed to the enclosing statement.
508: % That is, the statement \?{Browse {E next($)}}?
509: % has identical behavior to:
510: % \begin{ozdisplay}
511: % local X in
512: % {E next(X)}
513: % {Browse X}
514: % end
515: % \end{ozdisplay}
516: When running this example,
517: the first call
518: displays the solution \OzInline{[sol(nil\OzSpace{1}[1\OzSpace{1}2\OzSpace{1}3\OzSpace{1}4\OzSpace{1}5])]},
519: that is, a one-element list containing a solution.
520: Successive calls display the solutions
521: \OzInline{[sol([1]\OzSpace{1}[2\OzSpace{1}3\OzSpace{1}4\OzSpace{1}5])]}, ..., \OzInline{[sol([1\OzSpace{1}2\OzSpace{1}3\OzSpace{1}4\OzSpace{1}5]\OzSpace{1}nil)]}.
522: When there are no more solutions, then \OzInline{nil} is displayed
523: instead of a one-element list.
524:
525: The standard Oz approach is to use search only
526: for problems that require it.
527: To solve algorithmic problems,
528: one does not need to learn how to use search
529: in the language.
530: This is unlike Prolog,
531: where search is ubiquitous:
532: even procedure application is defined in terms
533: of resolution, and thus search.
534: In Oz, the \OzInline{\OzKeyword{choice}} statement explicitly creates
535: a choice point, and search abstractions
536: (such as \OzInline{Search.object}, above) encapsulate and control it.
537: However, the \OzInline{\OzKeyword{choice}} statement by itself is a bit too simplistic,
538: since the choice point is statically placed.
539: The usual way to add choice points in Oz
540: is with abstractions that dynamically create
541: a choice point whose alternatives
542: depend on the state of the computation.
543: The heuristics used are called the {\em distribution strategy}.
544: For example, the procedure \OzInline{FD.distribute} allows
545: to specify the distribution strategy
546: for problems using finite domain constraints.
547: Section~\ref{scalable} gives an example of this approach.
548:
549: \section{Concurrent logic programming}
550: \label{conclp}
551:
552: In {\em concurrent} logic programming,
553: programs are written as a set of don't-care predicates
554: and executed concurrently.
555: That is, at most one clause is chosen from each predicate
556: invocation, in a nondeterministic way from all the clauses
557: whose guards are true.
558: This style of logic programming is incomplete,
559: just like deterministic logic programming.
560: Only a small part of the search space is explored
561: due to the guarded clause selection.
562: The advantage is that programs are concurrent,
563: and concurrency is essential for programs that interact with
564: their environment, e.g., for agents, GUI programming, OS interaction, etc.
565: Many algorithmic problems are of this type.
566: Concurrency also permits a program to be organized into parts
567: that execute independently and interact only when needed.
568: This is an important software engineering property.
569:
570: In this section, we show how to do concurrent logic programming in Oz.
571: In fact, the full Oz language allows concurrency and search
572: to be used together (see Section~\ref{executionmodel}).
573: The clean integration of both in a single language
574: is one of the major strengths of Oz.
575: The integration was first achieved in Oz's immediate ancestor,
576: AKL, in 1990~\cite{akl}.
577: Oz shares many aspects with AKL but
578: improves over it in particular by being compositional
579: and higher-order.
580: % Oz can be seen as a compositional and higher-order version of AKL.
581:
582: \subsection{Implicit versus explicit concurrency}
583:
584: In early concurrent logic programming systems,
585: concurrency was implicit,
586: driven solely by data dependencies~\cite{Shapiro:89}.
587: Each body goal implicitly ran in its own thread.
588: The hope was that this would make parallel execution easy.
589: But this hope has not been realized, for several reasons.
590: The overhead of implicit concurrency is too high,
591: parallelism is limited without rewriting programs,
592: and detecting program termination is hard.
593: To reduce the overhead, it is possible to do lazy thread creation,
594: that is, to create a new thread only when the parent thread would suspend.
595: This approach has a nice slogan,
596: ``as sequential as possible, as concurrent as necessary,''
597: and it allows an efficient implementation.
598: But the approach is still inadequate
599: because reasoning about programs remains hard.
600:
601: After implementing and experimenting with
602: both implicit concurrency and lazy thread creation,
603: the current Oz decision is to do only explicit thread creation
604: (see Section~\ref{historysketch}).
605: Explicit thread creation
606: simplifies debugging and reasoning about programs,
607: and is efficient.
608: Furthermore, experience shows that parallelism (i.e., speedup) is
609: not harder to obtain than before; it is
610: still the programmer's responsibility to know what parts of
611: the program can potentially be run in parallel.
612:
613: \subsection{Concurrent producer-consumer}
614:
615: A classic example of concurrent logic programming
616: is the asynchronous producer-consumer.
617: The following program asynchronously generates a stream
618: of integers and sums them.
619: A {\em stream} is a list whose tail is an unbound logic variable.
620: The tail can itself be bound to a stream, and so forth.
621: \newpage
622: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{Generate\OzSpace{1}N\OzSpace{1}Limit\OzSpace{1}Xs\OzChar\}\OzEol
623: \OzSpace{6}\OzKeyword{if}\OzSpace{1}N<Limit\OzSpace{1}\OzKeyword{then}\OzSpace{1}Xr\OzSpace{1}\OzKeyword{in}\OzEol
624: \OzSpace{9}Xs=N|Xr\OzEol
625: \OzSpace{9}\OzChar\{Generate\OzSpace{1}N+1\OzSpace{1}Limit\OzSpace{1}Xr\OzChar\}\OzEol
626: \OzSpace{6}\OzKeyword{else}\OzSpace{1}Xs=nil\OzSpace{1}\OzKeyword{end}\OzEol
627: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
628: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{Sum\OzSpace{1}Xs\OzSpace{1}A\OzSpace{1}S\OzChar\}\OzEol
629: \OzSpace{6}\OzKeyword{case}\OzSpace{1}Xs\OzEol
630: \OzSpace{6}\OzKeyword{of}\OzSpace{1}X|Xr\OzSpace{1}\OzKeyword{then}\OzSpace{1}\OzChar\{Sum\OzSpace{1}Xr\OzSpace{1}A+X\OzSpace{1}S\OzChar\}\OzEol
631: \OzSpace{6}[]\OzSpace{1}nil\OzSpace{1}\OzKeyword{then}\OzSpace{1}S=A\OzEol
632: \OzSpace{6}\OzKeyword{end}\OzEol
633: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
634: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{local}\OzSpace{1}Xs\OzSpace{1}S\OzSpace{1}\OzKeyword{in}\OzEol
635: \OzSpace{6}\OzKeyword{thread}\OzSpace{1}\OzChar\{Generate\OzSpace{1}0\OzSpace{1}150000\OzSpace{1}Xs\OzChar\}\OzSpace{1}\OzKeyword{end}\OzSpace{2}\OzEolComment{\OzSpace{1}Producer\OzSpace{1}thread}\OzSpace{6}\OzKeyword{thread}\OzSpace{1}\OzChar\{Sum\OzSpace{1}Xs\OzSpace{1}0\OzSpace{1}S\OzChar\}\OzSpace{1}\OzKeyword{end}\OzSpace{12}\OzEolComment{\OzSpace{1}Consumer\OzSpace{1}thread}\OzSpace{6}\OzChar\{Browse\OzSpace{1}S\OzChar\}\OzEol
636: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
637: This executes as expected in the concurrent logic programming framework.
638: The producer, \OzInline{Generate},
639: and the consumer, \OzInline{Sum}, run in their own threads.
640: They communicate through the shared variable \OzInline{Xs},
641: which is a stream of integers.
642: The \OzInline{\OzKeyword{case}} statement in \OzInline{Sum} synchronizes on \OzInline{Xs} being bound to a value.
643:
644: This example has exactly one producer feeding exactly one consumer.
645: It therefore does not need a nondeterministic choice.
646: More general cases do, e.g., a client-server application
647: with more than one client feeding a server.
648: Without additional information,
649: the server never knows which client will send the next request.
650: Nondeterministic choice can be added directly to the language,
651: e.g., the \OzInline{WaitTwo} operation of Section~\ref{kernellang}.
652: It turns out to be more practical to add state instead.
653: Then nondeterministic choice is a consequence of having
654: both state and concurrency, as explained in Section~\ref{state}.
655:
656: \subsection{Lazy producer-consumer}
657: \label{lazyexample}
658:
659: In the above producer-consumer example,
660: it is the producer that decides how many
661: list elements to generate.
662: This is called {\em supply-driven} or {\em eager} execution.
663: This is an efficient technique if the total amount of work
664: is finite and
665: does not use many system resources (e.g., memory or calculation time).
666: On the other hand, if the total work potentially uses many
667: resources, then it may be better to use {\em demand-driven}
668: or {\em lazy} execution.
669: With lazy execution, the consumer decides
670: how many list elements to generate.
671: If an extremely large or a potentially unbounded number
672: of list elements are needed, then lazy execution will
673: use many fewer system resources at any given point in time.
674: Problems that are impractical with eager execution can become
675: practical with lazy execution.
676:
677: Lazy execution can be implemented in two ways in Oz.
678: The first way, which is applicable to any language,
679: is to use {\em explicit triggers}.
680: The producer and consumer are modified so that
681: the consumer asks the producer for additional list elements.
682: In our example,
683: the simplest way is to use logic variables as explicit triggers.
684: The consumer binds the end of a stream to \OzInline{X|\OzChar\_}.
685: The producer waits for this and binds \OzInline{X} to the next
686: list element.
687:
688: Explicit triggers are cumbersome because they require
689: the producer to accept explicit communications from the consumer.
690: A better way is for the language to support laziness directly.
691: That is, the language semantics would ensure that a function is
692: evaluated only if its result were needed.
693: Oz supports this syntactically
694: by annotating the function as ``\OzInline{lazy}''.
695: Here is how to do the previous
696: example with a lazy function that generates a potentially infinite list:
697: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{fun}\OzSpace{1}lazy\OzSpace{1}\OzChar\{Generate\OzSpace{1}N\OzChar\}\OzEol
698: \OzSpace{6}N|\OzChar\{Generate\OzSpace{1}N+1\OzChar\}\OzEol
699: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
700: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{Sum\OzSpace{1}Xs\OzSpace{1}Limit\OzSpace{1}A\OzSpace{1}S\OzChar\}\OzEol
701: \OzSpace{6}\OzKeyword{if}\OzSpace{1}Limit>0\OzSpace{1}\OzKeyword{then}\OzEol
702: \OzSpace{9}\OzKeyword{case}\OzSpace{1}Xs\OzEol
703: \OzSpace{9}\OzKeyword{of}\OzSpace{1}X|Xr\OzSpace{1}\OzKeyword{then}\OzEol
704: \OzSpace{12}\OzChar\{Sum\OzSpace{1}Xr\OzSpace{1}Limit-1\OzSpace{1}A+X\OzSpace{1}S\OzChar\}\OzEol
705: \OzSpace{9}\OzKeyword{end}\OzEol
706: \OzSpace{6}\OzKeyword{else}\OzSpace{1}S=A\OzSpace{1}\OzKeyword{end}\OzEol
707: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
708: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{local}\OzSpace{1}Xs\OzSpace{1}S\OzSpace{1}\OzKeyword{in}\OzEol
709: \OzSpace{6}\OzKeyword{thread}\OzSpace{1}Xs=\OzChar\{Generate\OzSpace{1}0\OzChar\}\OzSpace{1}\OzKeyword{end}\OzEol
710: \OzSpace{6}\OzKeyword{thread}\OzSpace{1}\OzChar\{Sum\OzSpace{1}Xs\OzSpace{1}150000\OzSpace{1}0\OzSpace{1}S\OzChar\}\OzSpace{1}\OzKeyword{end}\OzEol
711: \OzSpace{6}\OzChar\{Browse\OzSpace{1}S\OzChar\}\OzEol
712: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
713: Here the consumer, \OzInline{Sum}, decides
714: how many list elements should be generated.
715: The addition \OzInline{A+X} implicitly triggers
716: the generation of a new list element \OzInline{X}.
717: Lazy execution is part of the Oz execution
718: model; Section~\ref{lazykernel} explains how it works.
719:
720: \subsection{Coroutining}
721:
722: Sequential systems often support coroutining
723: as a simple way to get some of the abilities of concurrency.
724: Coroutining is a form of non-preemptive concurrency
725: in which a single locus of control is switched manually
726: between different parts of a program.
727: In our experience, a system with efficient
728: preemptive concurrency almost never needs coroutining.
729:
730: Most modern Prolog systems support coroutining.
731: The coroutining is either supported directly,
732: as in IC-Prolog~\cite{CM79:,Clar82a},
733: or indirectly
734: by means of an operation called {\tt freeze}
735: which provides data-driven computation.
736: The {\tt freeze(X,G)} operation,
737: sometimes called {\tt geler(X,G)}
738: from Prolog II which pioneered it~\cite{colmerauer82},
739: sets up the system to invoke the goal {\tt G} when
740: the variable {\tt X} is bound~\cite{artofprolog}.
741: With {\tt freeze} it is possible to have ``non-preemptive threads'' that
742: explicitly hand over control to each other by binding variables.
743: Because Prolog's search is based on global backtracking,
744: the ``threads'' are not independent: if a thread backtracks,
745: then other threads may be forced to backtrack as well.
746: Prolog programming techniques that depend on backtracking,
747: such as search, deep conditionals, and exceptions,
748: cannot be used if the program has to switch between threads.
749:
750: \section{Explicit state}
751: \label{state}
752:
753: From a theoretical point of view,
754: explicit state has often been considered
755: a forbidden fruit in logic programming.
756: We find that using explicit state
757: is important for fundamental reasons
758: related to program modularity
759: (see Chapter 4 of~\cite{book}).
760:
761: There exist tools to use state in Prolog while keeping
762: a logical semantics when possible.
763: See for example SICStus Objects~\cite{sicstus}, Prolog++~\cite{moss},
764: and the Logical State Threads package~\cite{lst97}.
765: An ancestor of the latter was used to help write
766: the Aquarius Prolog compiler~\cite{edcg,aquarius}.
767:
768: Functional programmers have also incorporated
769: state into functional languages, e.g., by means of
770: \texttt{set} operations in LISP/Scheme~\cite{commonlisp,abelson2},
771: references in ML~\cite{MilnerTofteHarper:90},
772: and monads in Haskell~\cite{Wadler:92c}.
773:
774: \subsection{Cells (mutable references)}
775:
776: State is an explicit part of the basic execution model in Oz.
777: The model defines the concept of {\em cell},
778: which is a kind of mutable reference.
779: A cell is a pair of a name \OzInline{C} and a reference \OzInline{X}.
780: There are two operations on cells:
781: \begin{oz2texdisplay}\OzSpace{2}\OzChar\{NewCell\OzSpace{1}X\OzSpace{1}C\OzChar\}\OzSpace{4}\OzEolComment{\OzSpace{1}Create\OzSpace{1}new\OzSpace{1}cell\OzSpace{1}with\OzSpace{1}name\OzSpace{1}C\OzSpace{1}and\OzSpace{1}content\OzSpace{1}X}\OzSpace{2}\OzChar\{Exchange\OzSpace{1}C\OzSpace{1}X\OzSpace{1}Y\OzChar\}\OzSpace{1}\OzEolComment{\OzSpace{1}Update\OzSpace{1}content\OzSpace{1}to\OzSpace{1}Y\OzSpace{1}and\OzSpace{1}bind\OzSpace{1}X\OzSpace{1}to\OzSpace{1}old\OzSpace{1}content}\end{oz2texdisplay}
782: Each \OzInline{Exchange} atomically accesses the current content and
783: defines a new content.
784:
785: Oz has a full-featured concurrent object system
786: which is completely defined in terms
787: of cells~\cite{HenzDiss:97,HenzOFCCP:97}.
788: The object system includes multiple inheritance,
789: fine-grained method access control,
790: and first-class messages.
791: Sections~\ref{executionmodel} gives more information
792: about cells and explains how they underlie the object system.
793:
794: \subsection{Ports (communication channels)}
795:
796: In this section we present another,
797: equivalent way to add state to the basic model.
798: This is the concept of {\em port}, which was pioneered by AKL.
799: A port is a pair of a name \OzInline{P} and a stream \OzInline{Xs}~\cite{portpaper}.
800: There are two operations on ports:
801: \begin{oz2texdisplay}\OzSpace{3}\OzChar\{NewPort\OzSpace{1}Xs\OzSpace{1}P\OzChar\}\OzSpace{2}\OzEolComment{\OzSpace{1}Create\OzSpace{1}new\OzSpace{1}port\OzSpace{1}with\OzSpace{1}name\OzSpace{1}P\OzSpace{1}and\OzSpace{1}stream\OzSpace{1}Xs}\OzSpace{3}\OzChar\{Send\OzSpace{1}P\OzSpace{1}X\OzChar\}\OzSpace{6}\OzEolComment{\OzSpace{1}Add\OzSpace{1}X\OzSpace{1}to\OzSpace{1}port's\OzSpace{1}stream\OzSpace{1}asynchronously}\end{oz2texdisplay}
802: Each \OzInline{Send} asynchronously adds one more element to the port's stream.
803: The port keeps an internal reference to the stream's unbound tail.
804: Repeated sends in the same thread cause the elements to appear
805: in the same order as the sends.
806: There are no other ordering constraints on the stream.
807:
808: Using ports gives us the ability to have named active objects.
809: An {\em active object}, in its simplest form,
810: pairs an object with a thread.
811: The thread reads a stream of internal and external messages,
812: and invokes the object for each message.
813: The Erlang language is based on this idea~\cite{erlang}.
814: Erlang extends it by adding
815: to each object a mailbox that does retrieval by pattern matching.
816:
817: With cells it is natural to define
818: non-active objects, called {\em passive objects},
819: shared between threads.
820: With ports it is natural to define
821: active objects that send messages to each other.
822: From a theoretical point of view,
823: these two programming styles have the same expressiveness,
824: since cells and ports can be defined in terms of each other
825: without changing time or space complexity~\cite{HenzOFCCP:97,needhamlauer78}.
826: They differ in practice,
827: since depending on the application
828: one style might be more convenient than the other.
829: Database applications, which are centered around a shared data repository,
830: find the shared object style natural.
831: Multi-agent applications,
832: defined in terms of collaborating active entities,
833: find the active object style natural.
834:
835: % While AKL objects are active objects that encapsulate a thread,
836: % the Oz object system has passive objects
837: % with separate threads~\cite{Meyer,ozobjects}.
838:
839: \subsection{Relevance to concurrent logic programming}
840:
841: From the perspective of concurrent logic programming,
842: explicit state amounts to the addition of
843: a constant-time $n$-way stream merge,
844: where $n$ can grow arbitrarily large at run-time.
845: That is, any number
846: of threads can concurrently send to the same port,
847: and each send will take constant time.
848: This can be seen as the ability to give
849: an {\em identity} to an active object.
850: The identity is a first-class value:
851: it can be stored in a data structure
852: and can be passed as an argument.
853: It is enough to know the identity to send
854: a message to the active object.
855:
856: Without explicit state it impossible
857: to build this kind of merge.
858: If $n$ is known only at run-time,
859: the only solution is to build a tree of stream mergers.
860: With $n$ senders, this multiplies
861: the message sending time by $O(\log n)$.
862: We know of no simple way to solve this problem
863: other than by adding explicit state to the execution model.
864:
865: \subsection{Creating an active object}
866:
867: Here is an example that uses a port to make an active object:
868: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{DisplayStream\OzSpace{1}Xs\OzChar\}\OzEol
869: \OzSpace{6}\OzKeyword{case}\OzSpace{1}Xs\OzSpace{1}\OzKeyword{of}\OzSpace{1}X|Xr\OzSpace{1}\OzKeyword{then}\OzSpace{1}\OzChar\{Browse\OzSpace{1}X\OzChar\}\OzSpace{1}\OzChar\{DisplayStream\OzSpace{1}Xr\OzChar\}\OzEol
870: \OzSpace{6}\OzKeyword{else}\OzSpace{1}\OzKeyword{skip}\OzSpace{1}\OzKeyword{end}\OzEol
871: \OzSpace{3}\OzKeyword{end}\OzEol
872: \OzEol
873: \OzSpace{3}\OzKeyword{declare}\OzSpace{1}P\OzSpace{1}\OzKeyword{in}\OzSpace{4}\OzEolComment{\OzSpace{1}P\OzSpace{1}has\OzSpace{1}global\OzSpace{1}scope}\OzSpace{3}\OzKeyword{local}\OzSpace{1}Xs\OzSpace{1}\OzKeyword{in}\OzSpace{5}\OzEolComment{\OzSpace{1}Xs\OzSpace{1}has\OzSpace{1}local\OzSpace{1}scope}\OzSpace{6}\OzChar\{NewPort\OzSpace{1}Xs\OzSpace{1}P\OzChar\}\OzEol
874: \OzSpace{6}\OzKeyword{thread}\OzSpace{1}\OzChar\{DisplayStream\OzSpace{1}Xs\OzChar\}\OzSpace{1}\OzKeyword{end}\OzEol
875: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
876: Sending to \OzInline{P} sends to the active object.
877: Any number of clients can send to the active object
878: concurrently:
879: \newpage
880: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{thread}\OzSpace{1}\OzChar\{Send\OzSpace{1}P\OzSpace{1}1\OzChar\}\OzSpace{1}\OzChar\{Send\OzSpace{1}P\OzSpace{1}2\OzChar\}\OzSpace{1}...\OzSpace{1}\OzKeyword{end}\OzSpace{3}\OzEolComment{\OzSpace{1}Client\OzSpace{1}1}\OzSpace{3}\OzKeyword{thread}\OzSpace{1}\OzChar\{Send\OzSpace{1}P\OzSpace{1}a\OzChar\}\OzSpace{1}\OzChar\{Send\OzSpace{1}P\OzSpace{1}b\OzChar\}\OzSpace{1}...\OzSpace{1}\OzKeyword{end}\OzSpace{3}\OzEolComment{\OzSpace{1}Client\OzSpace{1}2}\end{oz2texdisplay}
881: The elements \OzInline{1}, \OzInline{2}, \OzInline{a}, \OzInline{b}, etc., will appear
882: fairly on the stream \OzInline{Xs}.
883: Port fairness is guaranteed because of thread fairness
884: in the Mozart implementation.
885:
886: % \begin{ozdisplay}
887: % thread
888: % for X in Xs do {Browse X} end
889: % end
890: % \end{ozdisplay}
891: % The \?for? statement synchronizes on the stream
892: % just like \?DisplayStream?.
893:
894: Here is a more compact way to define the active object's thread:
895: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{thread}\OzEol
896: \OzSpace{6}\OzChar\{ForAll\OzSpace{1}Xs\OzSpace{1}\OzKeyword{proc}\OzSpace{1}\OzChar\{\OzChar\$\OzSpace{1}X\OzChar\}\OzSpace{1}\OzChar\{Browse\OzSpace{1}X\OzChar\}\OzSpace{1}\OzKeyword{end}\OzChar\}\OzEol
897: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
898: The notation \OzInline{\OzKeyword{proc}\OzSpace{1}\OzChar\{\OzChar\$\OzSpace{1}X\OzChar\}\OzSpace{1}...\OzSpace{1}\OzKeyword{end}} defines
899: an {\em anonymous} procedure value,
900: which is not bound to any identifier.
901: \OzInline{ForAll} is a higher-order procedure
902: that applies a unary procedure
903: to all elements of a list.
904: \OzInline{ForAll} keeps the dataflow synchronization
905: when traversing the list.
906: This is an example how higher-orderness can be used
907: to modularize a program: the iteration
908: is separated from the action to be performed
909: on each iteration.
910:
911: \section{More on search}
912: \label{moresearch}
913:
914: We have already introduced search
915: in Section~\ref{nondetlp}
916: by means of the \OzInline{\OzKeyword{choice}} statement and the
917: lazy depth-first abstraction \OzInline{Search.object}.
918: The programming style shown there is too limited
919: for many realistic problems.
920: This section shows
921: how to make search more practical in Oz.
922: We only scratch the surface of
923: how to use search in Oz; for more information
924: we suggest the Finite Domain and Finite Set
925: tutorials in the Mozart system documentation~\cite{fdtutorial,fstutorial}.
926:
927: \subsection{Aggregate search}
928: \label{aggreg}
929:
930: One of the powerful features of Prolog
931: is its ability to generate aggregates based
932: on complex queries, through the
933: built-in operations {\tt setof/3} and {\tt bagof/3}.
934: These are easy to do in Oz; they are
935: just special cases of search abstractions.
936: In this section
937: we show how to implement {\tt bagof/3}.
938: Consider the following small biblical database
939: (taken from~\cite{artofprolog}):
940: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{Father\OzSpace{1}F\OzSpace{1}C\OzChar\}\OzEol
941: \OzSpace{6}\OzKeyword{choice}\OzSpace{1}F=terach\OzSpace{2}C=abraham\OzEol
942: \OzSpace{10}[]\OzSpace{1}F=terach\OzSpace{2}C=nachor\OzEol
943: \OzSpace{10}[]\OzSpace{1}F=terach\OzSpace{2}C=haran\OzEol
944: \OzSpace{10}[]\OzSpace{1}F=abraham\OzSpace{1}C=isaac\OzEol
945: \OzSpace{10}[]\OzSpace{1}F=haran\OzSpace{3}C=lot\OzEol
946: \OzSpace{10}[]\OzSpace{1}F=haran\OzSpace{3}C=milcah\OzEol
947: \OzSpace{10}[]\OzSpace{1}F=haran\OzSpace{3}C=yiscah\OzEol
948: \OzSpace{6}\OzKeyword{end}\OzEol
949: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
950: Now consider the following Prolog predicate:
951: \begin{verbatim}
952: children1(X, Kids) :- bagof(K, father(X,K), Kids).
953: \end{verbatim}
954: This is defined in Oz as follows:
955: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{ChildrenFun\OzSpace{1}X\OzSpace{1}Kids\OzChar\}\OzEol
956: \OzSpace{3}F\OzSpace{1}\OzKeyword{in}\OzEol
957: \OzSpace{6}\OzKeyword{proc}\OzSpace{1}\OzChar\{F\OzSpace{1}K\OzChar\}\OzSpace{1}\OzChar\{Father\OzSpace{1}X\OzSpace{1}K\OzChar\}\OzSpace{1}\OzKeyword{end}\OzEol
958: \OzSpace{6}\OzChar\{Search.base.all\OzSpace{1}F\OzSpace{1}Kids\OzChar\}\OzEol
959: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
960: The procedure \OzInline{F} is a lexically-scoped closure:
961: it has the external reference \OzInline{X} hidden inside.
962: This can be written more compactly
963: with an anonymous procedure value:
964: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{ChildrenFun\OzSpace{1}X\OzSpace{1}Kids\OzChar\}\OzEol
965: \OzSpace{6}\OzChar\{Search.base.all\OzSpace{1}\OzKeyword{proc}\OzSpace{1}\OzChar\{\OzChar\$\OzSpace{1}K\OzChar\}\OzSpace{1}\OzChar\{Father\OzSpace{1}X\OzSpace{1}K\OzChar\}\OzSpace{1}\OzKeyword{end}\OzSpace{1}Kids\OzChar\}\OzEol
966: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
967: The \OzInline{Search.base.all} abstraction takes a one-argument
968: procedure and returns the list of all solutions to the procedure.
969: The example call:
970: \begin{oz2texdisplay}\OzSpace{3}\OzChar\{Browse\OzSpace{1}\OzChar\{ChildrenFun\OzSpace{1}terach\OzChar\}\OzChar\}\end{oz2texdisplay}
971: returns \OzInline{[abraham\OzSpace{1}nachor\OzSpace{1}haran]}.
972: The \OzInline{ChildrenFun} definition is deterministic;
973: if called with a known \OzInline{X} then it returns \OzInline{Kids}.
974: To search over different values of \OzInline{X}
975: we give the following definition instead:
976: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{ChildrenRel\OzSpace{1}X\OzSpace{1}Kids\OzChar\}\OzEol
977: \OzSpace{6}\OzChar\{Father\OzSpace{1}X\OzSpace{1}\OzChar\_\OzChar\}\OzEol
978: \OzSpace{6}\OzChar\{Search.base.all\OzSpace{1}\OzKeyword{proc}\OzSpace{1}\OzChar\{\OzChar\$\OzSpace{1}K\OzChar\}\OzSpace{1}\OzChar\{Father\OzSpace{1}X\OzSpace{1}K\OzChar\}\OzSpace{1}\OzKeyword{end}\OzSpace{1}Kids\OzChar\}\OzEol
979: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
980: The call \OzInline{\OzChar\{Father\OzSpace{1}X\OzSpace{1}\OzChar\_\OzChar\}} creates a choice point on \OzInline{X}.
981: The ``\OzInline{\OzChar\_}'' is syntactic sugar for \OzInline{\OzKeyword{local}\OzSpace{1}X\OzSpace{1}\OzKeyword{in}\OzSpace{1}X\OzSpace{1}\OzKeyword{end}},
982: which is just a new variable with a tiny scope.
983: The example call:
984: \begin{oz2texdisplay}\OzSpace{3}\OzChar\{Browse\OzSpace{1}\OzChar\{Search.base.all\OzEol
985: \OzSpace{5}\OzKeyword{proc}\OzSpace{1}\OzChar\{\OzChar\$\OzSpace{1}Q\OzChar\}\OzSpace{1}X\OzSpace{1}Kids\OzSpace{1}\OzKeyword{in}\OzSpace{1}\OzChar\{ChildrenRel\OzSpace{1}X\OzSpace{1}Kids\OzChar\}\OzSpace{1}Q=sol(X\OzSpace{1}Kids)\OzSpace{1}\OzKeyword{end}\OzChar\}\OzChar\}\end{oz2texdisplay}
986: returns:
987: \begin{oz2texdisplay}\OzSpace{3}[sol(terach\OzSpace{1}[abraham\OzSpace{1}nachor\OzSpace{1}haran])\OzEol
988: \OzSpace{4}sol(terach\OzSpace{1}[abraham\OzSpace{1}nachor\OzSpace{1}haran])\OzEol
989: \OzSpace{4}sol(terach\OzSpace{1}[abraham\OzSpace{1}nachor\OzSpace{1}haran])\OzEol
990: \OzSpace{4}sol(abraham\OzSpace{1}[isaac])\OzEol
991: \OzSpace{4}sol(haran\OzSpace{1}[lot\OzSpace{1}milcah\OzSpace{1}yiscah])\OzEol
992: \OzSpace{4}sol(haran\OzSpace{1}[lot\OzSpace{1}milcah\OzSpace{1}yiscah])\OzEol
993: \OzSpace{4}sol(haran\OzSpace{1}[lot\OzSpace{1}milcah\OzSpace{1}yiscah])]\end{oz2texdisplay}
994: In Prolog, {\tt bagof} can use existential quantification.
995: For example, the Prolog predicate:
996: \begin{verbatim}
997: children2(Kids) :- bagof(K, X^father(X,K), Kids).
998: \end{verbatim}
999: collects all children such that there exists a father.
1000: This is defined in Oz as follows:
1001: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{proc}\OzSpace{1}\OzChar\{Children2\OzSpace{1}Kids\OzChar\}\OzEol
1002: \OzSpace{6}\OzChar\{Search.base.all\OzSpace{1}\OzKeyword{proc}\OzSpace{1}\OzChar\{\OzChar\$\OzSpace{1}K\OzChar\}\OzSpace{1}\OzChar\{Father\OzSpace{1}\OzChar\_\OzSpace{1}K\OzChar\}\OzSpace{1}\OzKeyword{end}\OzSpace{1}Kids\OzChar\}\OzEol
1003: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
1004: The Oz solution uses \OzInline{\OzChar\_} to add a new existentially-scoped variable.
1005: The Prolog solution, on the other hand, introduces
1006: a new concept, namely the ``existential quantifier'' notation \verb+X^+,
1007: which only has meaning in terms of {\tt setof/3} and {\tt bagof/3}.
1008: The fact that this notation denotes
1009: an existential quantifier is arbitrary.
1010: The Oz solution introduces no new concepts.
1011: It really does existential quantification inside the search query.
1012:
1013: \subsection{Simple search procedures}
1014: \label{simplesearch}
1015:
1016: The procedure \OzInline{Search.base.all} shown in the previous section
1017: is just one of a whole set of search procedures provided by Oz
1018: for elementary nondeterministic logic programming.
1019: We give a short overview; for more information
1020: see the System Modules documentation in the
1021: Mozart system~\cite{systemmodules}.
1022: All procedures take as argument a unary procedure \OzInline{\OzChar\{P\OzSpace{1}X\OzChar\}},
1023: where \OzInline{X} is bound to a solution.
1024: Except for lazy search,
1025: they all provide depth-first search (one and all solution)
1026: and branch-and-bound search (with a cost function).
1027: Here are the procedures:
1028: \begin{itemize}
1029: \item {\bf Basic search}. This is the simplest to use;
1030: no extra parameters are needed.
1031:
1032: \item {\bf General-purpose search}. This allows parameterizing the search
1033: with the maximal recomputation distance
1034: (for optimizing time and memory use),
1035: with an asynchronous kill procedure to allow stopping infinite searches,
1036: and with the option to return solutions either directly or
1037: encapsulated in computation spaces (see Section~\ref{compspaces}).
1038: Search implemented with spaces
1039: using strategies combining cloning and recomputation
1040: is competitive in time and memory
1041: with systems using trailing~\cite{Schulte:ICLP99}.
1042: Using encapsulation,
1043: general-purpose search can be used
1044: as a primitive to build more sophisticated searches.
1045:
1046: \item {\bf Parallel search}.
1047: When provided with a list of machines, this will spread out the
1048: search process over these machines transparently.
1049: We have benchmarked realistic constraint problems
1050: on up to six machines with linear speedups~\cite{Schulte:02,SchulteDiss:00,Schulte:00b}.
1051: The order in which the search tree is explored is nondeterministic,
1052: and is likely to be different from depth-first or breadth-first.
1053: If the entire tree is explored, then the number of exploration steps
1054: is the same as depth-first search.
1055: The speedup is a consequence of this fact
1056: together with the spreading of work.
1057:
1058: \item {\bf Lazy search}. This provides next solution and
1059: last solution operations,
1060: a stop operation, and a close operation.
1061: This is a first-class Prolog top level.
1062:
1063: \item {\bf Explorer search}.
1064: The Explorer is a concurrent graphic tool that allows to
1065: visualize and interactively guide
1066: the search process~\cite{explorer,Schulte:97}.
1067: It is invaluable for search debugging and for gaining understanding of
1068: the structure of the problem.
1069: \end{itemize}
1070: All of these procedures are implemented in Oz using
1071: computation spaces (see Section~\ref{compspaces}).
1072: Many more specialized search procedures are available for constraint
1073: programming, and the user can easily define his or her own.
1074:
1075: \begin{figure}
1076: \figrule
1077: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{functor}\OzSpace{1}Fractions\OzSpace{3}\OzEolComment{\OzSpace{1}Name\OzSpace{1}of\OzSpace{1}module\OzSpace{1}specification}\OzSpace{6}\OzKeyword{import}\OzSpace{1}FD\OzSpace{8}\OzEolComment{\OzSpace{1}Needs\OzSpace{1}the\OzSpace{1}module\OzSpace{1}FD}\OzSpace{6}\OzKeyword{export}\OzSpace{1}script:P\OzSpace{2}\OzEolComment{\OzSpace{1}Procedure\OzSpace{1}P\OzSpace{1}defines\OzSpace{1}the\OzSpace{1}problem}\OzSpace{3}\OzKeyword{define}\OzEol
1078: \OzSpace{6}\OzKeyword{proc}\OzSpace{1}\OzChar\{P\OzSpace{1}Sol\OzChar\}\OzEol
1079: \OzSpace{9}A\OzSpace{1}B\OzSpace{1}C\OzSpace{1}D\OzSpace{1}E\OzSpace{1}F\OzSpace{1}G\OzSpace{1}H\OzSpace{1}I\OzSpace{1}BC\OzSpace{1}EF\OzSpace{1}HI\OzEol
1080: \OzSpace{6}\OzKeyword{in}\OzEol
1081: \OzSpace{9}Sol=sol(a:A\OzSpace{1}b:B\OzSpace{1}c:C\OzSpace{1}d:D\OzSpace{1}e:E\OzSpace{1}f:F\OzSpace{1}g:G\OzSpace{1}h:H\OzSpace{1}i:I)\OzEol
1082: \OzSpace{9}BC=\OzChar\{FD.decl\OzChar\}\OzSpace{1}EF=\OzChar\{FD.decl\OzChar\}\OzSpace{1}HI=\OzChar\{FD.decl\OzChar\}\OzEol
1083: \OzSpace{9}\OzEolComment{\OzChar\%\OzChar\%\OzSpace{1}The\OzSpace{1}constraints:}\OzSpace{9}Sol:::1\OzChar\#9\OzSpace{10}\OzEolComment{\OzSpace{1}Each\OzSpace{1}letter\OzSpace{1}represents\OzSpace{1}a\OzSpace{1}digit}\OzSpace{9}\OzChar\{FD.distinct\OzSpace{1}Sol\OzChar\}\OzSpace{2}\OzEolComment{\OzSpace{1}All\OzSpace{1}digits\OzSpace{1}are\OzSpace{1}different}\OzSpace{9}BC=:10*B+C\OzSpace{9}\OzEolComment{\OzSpace{1}Definition\OzSpace{1}of\OzSpace{1}BC}\OzSpace{9}EF=:10*E+F\OzSpace{9}\OzEolComment{\OzSpace{1}Definition\OzSpace{1}of\OzSpace{1}EF}\OzSpace{9}HI=:10*H+I\OzSpace{9}\OzEolComment{\OzSpace{1}Definition\OzSpace{1}of\OzSpace{1}HI}\OzSpace{9}A*EF*HI+D*BC*HI+G*BC*EF=:BC*EF*HI\OzSpace{2}\OzEolComment{\OzSpace{1}Main\OzSpace{1}constraint}\OzSpace{9}\OzEolComment{\OzChar\%\OzChar\%\OzSpace{1}The\OzSpace{1}distribution\OzSpace{1}strategy:}\OzSpace{9}\OzChar\{FD.distribute\OzSpace{1}ff\OzSpace{1}Sol\OzChar\}\OzEol
1084: \OzSpace{6}\OzKeyword{end}\OzEol
1085: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
1086: \caption{A more scalable way to do search}
1087: \label{scalablesearch}
1088: \figrule
1089: \end{figure}
1090:
1091: \subsection{A more scalable way to do search}
1092: \label{scalable}
1093:
1094: The original motivation for doing search in Oz comes
1095: from constraint programming.
1096: To do search, Oz uses a concurrent version of
1097: the following approach, which is commonly used
1098: in (sequential) constraint logic programming:
1099: \begin{itemize}
1100: \item First, declaratively specify the problem by means of constraints.
1101: The constraints have an operational as well as a declarative reading.
1102: The operational reading specifies the deductions that the constraints
1103: can make locally.
1104: To get good results, the constraints must be able
1105: to do deductions over big parts of the problem
1106: (i.e., deductions that consider many problem variables together).
1107: Such constraints are called ``global''.
1108: \item Second, define and explore the search tree in a controlled way,
1109: using heuristics to exploit the problem structure.
1110: The general technique is called ``propagate and distribute'',
1111: because it alternates propagation steps
1112: (where the constraints propagate information amongst themselves)
1113: with distribution steps
1114: (where a choice is selected in a choice point).\footnote{The term
1115: ``distribution'' as used here refers to the distribution of $\wedge$ over $\vee$
1116: in the logical formula $c \wedge (a \vee b)$
1117: and has nothing to do with distributed systems consisting of
1118: independent computers connected by a network.}
1119: See, e.g.,~\cite{constraints96}, for more explanation.
1120: \end{itemize}
1121: This approach is widely applicable.
1122: For example, it is being applied successfully
1123: to computational linguistics~\cite{duchier-mol6,CP-NL,DucGarNie99}.
1124: In this section, we show how to solve a simple integer puzzle.
1125: Consider the problem of finding nine distinct digits $A$, $B$, ..., $I$,
1126: so that the following equation holds:
1127: \begin{quote}
1128: $A / BC + D / EF + G / HI = 1$
1129: \end{quote}
1130: Here, $BC$ represents the integer $10 \times B+C$.
1131: Figure~\ref{scalablesearch} shows how to specify this
1132: as a constraint problem.
1133: The unary procedure \OzInline{\OzChar\{P\OzSpace{1}Sol\OzChar\}} fully defines the problem
1134: and the distribution strategy.
1135: The problem is specified as a conjunction of
1136: constraints on \OzInline{Sol},
1137: which is bound to a record that contains the solution.\footnote{To be
1138: precise, \OzInline{Sol} is bound to a feature tree,
1139: which is a logical formulation of a record.}
1140: The record has fields \OzInline{a}, ..., \OzInline{i},
1141: one for each solution variable.
1142: The problem constraints
1143: are expressed in terms of {\em finite domains},
1144: i.e., finite sets of integers.
1145: For example, the notation \OzInline{1\OzChar\#9} represents the set $\{1, 2, ..., 9\}$.
1146: The constraints are defined
1147: in the module \OzInline{FD}~\cite{systemmodules}.
1148: For example, \OzInline{FD.distinct} is a global constraint that asserts
1149: that all its component variables are distinct integers.
1150:
1151: \OzInline{Fractions} defines \OzInline{P} inside a {\em functor},
1152: i.e., a module specification, in Oz terminology.
1153: The functor defines explicitly what
1154: process-specific resources the module needs.
1155: This allows us to set up a parallel search engine
1156: that spreads the constraint solving over several
1157: machines~\cite{modules-98}.
1158: If execution is always in the same process,
1159: then the functor is not needed and it is enough to
1160: define the procedure \OzInline{P}.
1161: Let's set up a parallel search engine:
1162: \begin{oz2texdisplay}\OzSpace{3}E=\OzChar\{New\OzSpace{1}Search.parallel\OzEol
1163: \OzSpace{10}init(adventure:1\OzChar\#rsh\OzSpace{1}galley:1\OzChar\#rsh\OzSpace{1}norge:1\OzChar\#rsh)\OzChar\}\end{oz2texdisplay}
1164: This sets up an engine on the three machines
1165: \OzInline{adventure}, \OzInline{galley}, and \OzInline{norge}.
1166: The engine is implemented using computation spaces
1167: (see Section~\ref{compspaces})
1168: and Mozart's support for distributed computing (see~\cite{ngc98}).
1169: A single process is created on each of these machines
1170: using the remote shell operation \OzInline{rsh}
1171: (other operations are possible including secure shell \OzInline{ssh}
1172: for secure communication and local shell \OzInline{sh}
1173: for shared-memory multiprocessors).
1174: The following command does parallel search
1175: on the problem specified in \OzInline{Fractions}:
1176: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{local}\OzSpace{1}X\OzSpace{1}\OzKeyword{in}\OzSpace{1}\OzChar\{E\OzSpace{1}all(Fractions\OzSpace{1}X)\OzChar\}\OzSpace{1}\OzChar\{Browse\OzSpace{1}X\OzChar\}\OzSpace{1}\OzKeyword{end}\end{oz2texdisplay}
1177: This installs the functor \OzInline{Fractions} on each of
1178: the three machines and generates all the solutions.
1179: This is an example of a more scalable way to do search:
1180: first use global constraints and search heuristics,
1181: and then use parallel execution if necessary for performance.
1182:
1183: Oz is currently one of the
1184: most advanced languages for programming search.
1185: Competitors are
1186: CLAIRE and SaLSA~\cite{claire,salsa,caseau_meta_cp99}
1187: and OPL~\cite{opl}.
1188: Search is also an important part
1189: of constraint programming in general~\cite{constraintprogramming}.
1190:
1191: % \section{A note on syntax}
1192: %
1193: % The examples in the previous section may seem verbose in Oz.
1194: % This article uses a subset of Oz syntax for simplicity.
1195: % The subset does not have the syntactic short-cuts,
1196: % e.g., nesting and functional notation,
1197: % commonly used by Oz programmers.
1198: % For examplle, with nesting notation
1199: % the last example in Section~\ref{aggres} becomes:
1200: % \begin{ozdisplay}
1201: % proc {Children2 Kids}
1202: % {Search.base.all proc {$ K} {Father _ K} end Kids}
1203: % end
1204: % \end{ozdisplay}
1205: % See the Oz tutorial for an explanation of what this means~\cite{tutorial}.
1206:
1207: \section{The Oz execution model}
1208: \label{executionmodel}
1209:
1210: So far, we have highlighted different parts of Oz without
1211: showing how they interact,
1212: something like the proverbial elephant that
1213: is different things to different people.
1214: This section gives the simple execution model that underlies it all.
1215: We define the execution model in
1216: terms of a {\em store} (Section~\ref{store})
1217: and a {\em kernel language} (Section~\ref{kernellang}).
1218: Section~\ref{multiparadigm} explains how
1219: different subsets of the kernel language
1220: support different programming paradigms.
1221: The section also explains why supporting
1222: multiple paradigms is useful.
1223: Finally, Section~\ref{compspaces} defines
1224: computation spaces and how they are used
1225: to program search.
1226:
1227: \begin{figure}
1228: \figrule
1229: \psfig{file=model3.eps,width=\textwidth}
1230: \caption{The Oz store.}\label{storefig}
1231: \figrule
1232: \end{figure}
1233:
1234: \subsection{The store}
1235: \label{store}
1236:
1237: The Oz store
1238: consists of four parts (see Figure~\ref{storefig}):
1239: a thread store, a constraint store,
1240: a mutable store, and a trigger store.
1241: The constraint store contains
1242: equality constraints over the domain of rational trees.
1243: In other words, this store contains
1244: logic variables that are either unbound or bound.
1245: A bound variable
1246: references a term (i.e., atom, record, procedure, or name)
1247: whose arguments themselves may be bound or unbound.
1248: Unbound variables can be bound to unbound variables,
1249: in which case they become identical references.
1250: The constraint store is {\em monotonic},
1251: i.e., bindings can only be added, not removed or changed.
1252:
1253: The mutable store consists of
1254: mutable references into the constraint store.
1255: Mutable references
1256: are also called {\em cells}~\cite{HenzOFCCP:97}.
1257: A mutable reference consists of two parts:
1258: its {\em name}, which is a value,
1259: and its {\em content}, which is
1260: a reference into the constraint store.
1261: The mutable store is {\em nonmonotonic}
1262: because a mutable reference can be changed.
1263:
1264: The trigger store consists of {\em triggers},
1265: which are pairs of variables and one-argument procedures.
1266: Since these triggers are part of the basic execution model,
1267: they are sometimes called {\em implicit triggers},
1268: as opposed to the explicit triggers of Section~\ref{lazyexample}.
1269: Triggers implement by-need computation (i.e., lazy execution)
1270: and are installed with the \OzInline{ByNeed} operation.
1271: We will not say much about triggers in this article.
1272: For more information, see~\cite{book,futures}.
1273:
1274: The thread store consists of a set of threads.
1275: Each thread is defined by a statement $S_i$.
1276: Threads can only have references in the constraint store,
1277: not into the other stores.
1278: This means that
1279: the only way for threads to communicate and synchronize
1280: is through shared references in the constraint store.
1281: We say a thread is {\em runnable}, also called {\em ready},
1282: if it can execute its statement.
1283: Threads are {\em dataflow} threads, i.e.,
1284: a thread becomes runnable
1285: when the arguments needed by its statement are bound.
1286: If an argument is unbound
1287: then the thread automatically suspends until
1288: the argument is bound.
1289: Since the constraint store is monotonic,
1290: a thread that is runnable
1291: will stay runnable at least until
1292: it executes one step of its statement.
1293: The system guarantees weak fairness, which
1294: implies that a runnable thread will eventually execute.
1295:
1296: \begin{figure}
1297: \figrule
1298: % \begin{center}
1299: \begin{tabular}{@{}lr@{~}l@{~}l@{}}
1300: \multicolumn{2}{@{}l@{~}}{\nt{s} ::=} & \OzInline{\OzKeyword{skip}} & \\
1301: & $|$ & \nt{x}${}_1$=\nt{x}${}_2$ & \\
1302: & $|$ & \nt{x}=\nt{l}(\nt{f}${}_1$:\nt{x}${}_1$ ...
1303: \nt{f}${}_n$:\nt{x}${}_n$)
1304: & \\
1305: & $|$ & \nt{s}${}_1$ \nt{s}${}_2$ & \\
1306: & $|$ & \OzInline{\OzKeyword{local}} \nt{x} \OzInline{\OzKeyword{in}} \nt{s} \OzInline{\OzKeyword{end}} & \\
1307: & $|$ & \OzInline{\OzKeyword{if}} \nt{x} \OzInline{\OzKeyword{then}} \nt{s}${}_1$ \OzInline{\OzKeyword{else}} \nt{s}${}_2$ \OzInline{\OzKeyword{end}}
1308: & \\
1309: & $|$ & \OzInline{\OzKeyword{case}} \nt{x} \OzInline{\OzKeyword{of}}
1310: \nt{l}(\nt{f}${}_1$:\nt{x}${}_1$ ... \nt{f}${}_n$:\nt{x}${}_n$)
1311: \OzInline{\OzKeyword{then}} \nt{s}${}_1$ \OzInline{\OzKeyword{else}} \nt{s}${}_2$ \OzInline{\OzKeyword{end}}
1312: & \\
1313: & $|$ & \OzInline{\OzKeyword{proc}\OzSpace{1}\OzChar\{}\nt{x} \nt{y}${}_1$ ... \nt{y}${}_n$\OzInline{\OzChar\}} \nt{s} \OzInline{\OzKeyword{end}} & \\
1314: & $|$ & \OzInline{\OzChar\{}\nt{x} \nt{y}${}_1$ ... \nt{y}${}_n$\OzInline{\OzChar\}} & {\em CORE} \\
1315: & & \\
1316: & $|$ & \OzInline{\OzKeyword{thread}} \nt{s} \OzInline{\OzKeyword{end}} & {\em CONCURRENCY} \\
1317: & & \\
1318: & $|$ & \OzInline{\OzChar\{ByNeed} \nt{x} \nt{y}\OzInline{\OzChar\}} & {\em LAZINESS} \\
1319: & & \\
1320: & $|$ & \OzInline{\OzKeyword{try}} \nt{s}${}_1$ \OzInline{\OzKeyword{catch}} \nt{x} \OzInline{\OzKeyword{then}} \nt{s}${}_2$ \OzInline{\OzKeyword{end}} & \\
1321: & $|$ & \OzInline{\OzKeyword{raise}} \nt{x} \OzInline{\OzKeyword{end}} & {\em EXCEPTIONS} \\
1322: & & \\
1323: & $|$ & \OzInline{\OzChar\{NewName} \nt{x}\OzInline{\OzChar\}} & {\em SECURITY} \\
1324: & & \\
1325: & $|$ & \OzInline{\OzChar\{IsDet} \nt{x} \nt{y}\OzInline{\OzChar\}} & \\
1326: & $|$ & \OzInline{\OzChar\{NewCell} \nt{x} \nt{y}\OzInline{\OzChar\}} & \\
1327: & $|$ & \OzInline{\OzChar\{Exchange} \nt{x} \nt{y} \nt{z}\OzInline{\OzChar\}} & {\em STATE} \\
1328: & & \\
1329: & $|$ & \nt{space} & {\em SEARCH} \\
1330: \end{tabular}
1331: \caption{The Oz kernel language.}\label{kernel}
1332: \figrule
1333: % \end{center}
1334: \end{figure}
1335:
1336: \subsection{The kernel language}
1337: \label{kernellang}
1338: \label{lazykernel}
1339:
1340: All Oz execution can be defined
1341: in terms of a simple kernel language,
1342: whose syntax is defined in Figure~\ref{kernel}.
1343: The full Oz language provides syntactic
1344: support for additional language entities
1345: (such as functions, ports, objects, classes, and functors).
1346: The system hides their efficient implementation
1347: while respecting their definitions
1348: in terms of the kernel language.
1349: This performance optimization
1350: can be seen as a second kernel language,
1351: in between full Oz and the kernel language.
1352: The second kernel language is implemented directly.
1353:
1354: From the kernel language viewpoint,
1355: $n$-ary functions are just $(n+1)$-ary procedures,
1356: where the last argument is the function's output.
1357: In Figure~\ref{kernel},
1358: statements are denoted by \nt{s},
1359: computation space operations by
1360: \nt{space} (see Figure~\ref{compspacesfig}),
1361: logic variables by \nt{x}, \nt{y}, \nt{z},
1362: record labels by \nt{l},
1363: and record field names by \nt{f}.
1364:
1365: The semantics of the kernel language is given
1366: in~\cite{book} (except for spaces)
1367: and~\cite{Schulte:02,SchulteDiss:00} (for spaces).
1368: For comparison,
1369: the semantics of the original Oz language
1370: is given in~\cite{kerneloz}.
1371: The kernel language splits naturally into seven parts:
1372: \begin{itemize}
1373: \item {\em CORE}: The core is
1374: strict functional programming over a constraint store.
1375: This is exactly deterministic logic programming with
1376: explicit sequential control.
1377: The \OzInline{\OzKeyword{if}} statement expects a boolean argument
1378: (\OzInline{\OzKeyword{true}} or \OzInline{\OzKeyword{false}}).
1379: The \OzInline{\OzKeyword{case}} statement does pattern matching.
1380: The \OzInline{\OzKeyword{local}} statement introduces new variables
1381: (\OzInline{\OzKeyword{declare}} is a syntactic variant whose scope extends
1382: over the whole program).
1383:
1384: \item {\em CONCURRENCY}:
1385: The concurrency support adds explicit thread creation.
1386: Together with the core, this gives {\em dataflow concurrency},
1387: which is a form of declarative concurrency.
1388: Compared to a sequential program,
1389: this gives the same results
1390: but incrementally instead of all at once.
1391: This is deterministic logic programming with
1392: more flexible control than the core alone.
1393: This is discussed at length in~\cite{book}.
1394:
1395: \item {\em LAZINESS}:
1396: The laziness support adds
1397: the \OzInline{ByNeed} operation, which allows to
1398: express lazy execution, which is the basic idea
1399: of nonstrict functional languages
1400: such as Haskell~\cite{futures,Mehl:diss,haskell}.\footnote{In Mozart,
1401: the module \OzInline{Value} contains this operation: \OzInline{ByNeed=Value.byNeed}.}
1402: Together with the core, this gives {\em demand-driven concurrency},
1403: which is another form of declarative concurrency.
1404: Lazy execution gives the same results as eager execution,
1405: but calculates only what is needed to achieve the results.
1406: Again, this is deterministic logic programming with
1407: more flexible control than the core alone.
1408: This is important for resource management and program modularity.
1409: Lazy execution can give results in cases
1410: when eager execution does not terminate.
1411:
1412: \item {\em EXCEPTIONS}:
1413: The exception-handling support adds
1414: an operation, \OzInline{\OzKeyword{try}}, to create an exception context
1415: and an operation, \OzInline{\OzKeyword{raise}}, to jump to the innermost
1416: enclosing exception context.
1417:
1418: \item {\em SECURITY}:
1419: The security support adds {\em name values},
1420: which are unforgeable constants that do not
1421: have a printable representation.
1422: Calling \OzInline{\OzChar\{NewName\OzSpace{1}X\OzChar\}} creates a fresh name
1423: and binds it to \OzInline{X}.
1424: A name is a first-class ``right'' or ``key''
1425: that supports many programming techniques
1426: related to security and encapsulation.
1427:
1428: \item {\em STATE}:
1429: The state support adds explicit cell creation
1430: and an exchange operation, which atomically
1431: reads a cell's content and replaces it with a new content.
1432: This is sufficient for
1433: sequential object-oriented programming~\cite{opm,HenzDiss:97,HenzOFCCP:97}.
1434: Another, equivalent way to add state
1435: is by means of ports, which are explained in Section~\ref{state}.
1436:
1437: \item {\em SEARCH}:
1438: The search support adds operations on computation spaces
1439: (shown as \nt{space}), which are explained in Section~\ref{compspaces}.
1440: This allows to express nondeterministic logic programming
1441: (see Sections~\ref{nondetlp} and~\ref{moresearch}).
1442: A computation space encapsulates a choice point,
1443: i.e., don't-know nondeterminism,
1444: allowing the program to decide how to pick alternatives.
1445: Section~\ref{compspaces} explains spaces in
1446: more detail and shows how to program search with them.
1447: The \OzInline{\OzKeyword{choice}} statement, which is used in the examples
1448: of Sections~\ref{nondetlp} and~\ref{aggreg},
1449: can be programmed with spaces (see Section~\ref{andorradis}).
1450:
1451: % The laziness support adds
1452: % the \?Future? and \?ByNeed? operations, which allow to control
1453: % evaluation order~\cite{futures,Mehl:diss}.\footnote{In Mozart,
1454: % these operations are in the module \?Value?:
1455: % \?Future=Value.'!!'? and \?ByNeed=Value.byNeed?.}
1456: % The \?{Future X Y}? operation makes \?Y? a
1457: % read-only view of the variable \?X?
1458: % (called a {\em future} in the Oz documentation).\footnote{A
1459: % read-only variable is not quite a future in the sense
1460: % that Halstead defines it~\cite{halstead}.
1461: % Reference~\cite{toplas99} shows how to define
1462: % futures in terms of read-only variables.}
1463: % That is, binding \?X? will also bind \?Y?,
1464: % but any attempt to bind \?Y? will suspend.
1465: % This allows enforcing encapsulation for
1466: % abstract data types.
1467: % For example, a port's stream is a read-only variable.
1468: % Read-only variables can
1469: % also enforce directionality for functional programming.
1470: % The \?{ByNeed P X}? operation
1471: % creates a future \?X?.
1472: % When the value of \?X? is needed,
1473: % then the procedure \?{P Y}? is executed
1474: % in a new thread with a fresh variable \?Y?.
1475: % When \?P? is fully reduced, then \?Y? is bound to \?X?.
1476: % This allows to express lazy evaluation
1477: % as provided by functional languages such as Haskell~\cite{haskell}.
1478:
1479: \end{itemize}
1480:
1481: \subsubsection{Concurrency and state}
1482:
1483: Adding both concurrency and state to the core
1484: results in the most expressive computation model.
1485: There are two basic approaches to program in it:
1486: message passing with active objects or
1487: atomic actions on shared state.
1488: Active objects are used in Erlang~\cite{erlang}.
1489: Atomic actions are used in Java
1490: and other concurrent object-oriented languages~\cite{lea2}.
1491: These two approaches have the same expressive power,
1492: but are appropriate for different classes of applications
1493: (multi-agent versus data-centered)~\cite{book,needhamlauer78}.
1494:
1495: \subsubsection{Nondeterministic choice}
1496:
1497: Concurrent logic programming is obtained by
1498: extending the core with concurrency and nondeterministic choice.
1499: This gives a model that is more expressive than
1500: declarative concurrency and less expressive
1501: than concurrency and state used together.
1502: Nondeterministic choice means to wait concurrently
1503: for one of several conditions to become true.
1504: For example, we could add the operation \OzInline{WaitTwo}
1505: to the core with concurrency.
1506: \OzInline{\OzChar\{WaitTwo\OzSpace{1}X\OzSpace{1}Y\OzChar\}} blocks until either \OzInline{X} or \OzInline{Y}
1507: is bound to a nonvariable term.\footnote{In Mozart,
1508: the module \OzInline{Record} contains this operation:
1509: \OzInline{\OzChar\{WaitTwo\OzSpace{1}X\OzSpace{1}Y\OzChar\}} is written as \OzInline{\OzChar\{Record.waitOr\OzSpace{1}X\OzChar\#Y\OzChar\}}.}
1510: It then returns with 1 or 2.
1511: It can return 1 if \OzInline{X} is bound and 2 if \OzInline{Y} is bound.
1512: \OzInline{WaitTwo} does not need to be added as an additional concept;
1513: it can be programmed in the core with concurrency and state.
1514:
1515: \subsubsection{Lazy functions}
1516:
1517: The \OzInline{lazy} annotation used in Section~\ref{lazyexample}
1518: is defined in terms of \OzInline{ByNeed}.
1519: Calling \OzInline{\OzChar\{ByNeed\OzSpace{1}P\OzSpace{1}X\OzChar\}}
1520: adds the trigger \OzInline{(X,P)} to the trigger store.
1521: This makes \OzInline{X} behave as a read-only variable.
1522: Doing a computation that needs \OzInline{X} or attempts to bind \OzInline{X}
1523: will block the computation,
1524: execute \OzInline{\OzChar\{P\OzSpace{1}Y\OzChar\}} in a new thread,
1525: bind \OzInline{Y} to \OzInline{X}, and then continue.
1526: We say a value is {\em needed} by an operation if the
1527: thread executing the operation would suspend if the
1528: value were not present.
1529: For example, the function:
1530: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{fun}\OzSpace{1}lazy\OzSpace{1}\OzChar\{Generate\OzSpace{1}N\OzChar\}\OzEol
1531: \OzSpace{6}N|\OzChar\{Generate\OzSpace{1}N+1\OzChar\}\OzEol
1532: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
1533: is defined as:
1534: \newpage
1535: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{fun}\OzSpace{1}\OzChar\{Generate\OzSpace{1}N\OzChar\}\OzEol
1536: \OzSpace{3}P\OzSpace{1}X\OzSpace{1}\OzKeyword{in}\OzEol
1537: \OzSpace{6}\OzKeyword{proc}\OzSpace{1}\OzChar\{P\OzSpace{1}Y\OzChar\}\OzSpace{1}Y=N|\OzChar\{Generate\OzSpace{1}N+1\OzChar\}\OzSpace{1}\OzKeyword{end}\OzEol
1538: \OzSpace{6}\OzChar\{ByNeed\OzSpace{1}P\OzSpace{1}X\OzChar\}\OzEol
1539: \OzSpace{6}X\OzEol
1540: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
1541: \OzInline{P} will only be called when
1542: the value of \OzInline{\OzChar\{Generate\OzSpace{1}N\OzChar\}} is needed.
1543: We make two comments about this definition.
1544: First, the \OzInline{lazy} annotation is given explicitly by the programmer.
1545: Functions without it are eager.
1546: Second, Mozart threads are extremely lightweight,
1547: so the definition is practical.
1548: This is a different approach than in nonstrict languages such as Haskell,
1549: where lazy evaluation is the default and strictness analysis
1550: is used to regain the efficiency
1551: of eager evaluation~\cite{haskell}.
1552:
1553: % \subsubsection{Currying}
1554: %
1555: % Currying is a style of functional programming that combines
1556: % three features:
1557: % \begin{itemize}
1558: % \item All functions are one-argument functions.
1559: % \item The syntax is designed to make this concise.
1560: % \item The compiler is designed to make this efficient
1561: % (implementing an $n$-ary currified function
1562: % as a standard $n$-ary function where possible).
1563: % \end{itemize}
1564: % In those cases where it can
1565: % be used, currying makes programs more concise. But it puts
1566: % unnatural emphasis on abstracting away arguments in one particular
1567: % order, i.e., from the last argument to the first.
1568: % Other orders are penalized.
1569: % It is possible to have currying without this bias, e.g.,
1570: % A\"{\i}t-Kaci's label-selective lambda calculus allows
1571: % to curry in any order.
1572: % Oz does not have any special support for currying.
1573: % It is possible to write functional programs in Oz
1574: % with only one-argument functions, but it is cumbersome.
1575: % We have not found any compelling argument to include currying,
1576: % and since it complicates the compiler, we do not support it.
1577:
1578: % Add a sixth category, 'ACCESS CONTROL' containing Future and NewName?
1579:
1580: % The kernel language of Figure~\ref{kernel} gives the basic operations
1581: % that are interesting from the viewpoint of multiparadigm programming.
1582: % The complete kernel language has a few more operations, which we
1583: % summarize briefly.
1584: % First of all, each data type has a complete set of operations,
1585: % e.g., threads, cells, records, integers, etc., have more operations
1586: % than are listed.
1587: % Second, the \?{NewName X}? operation creates new instances of
1588: % pure unforgeable names.
1589: % These names are a particular kind of Oz atomic value.
1590: % They are essential to implement fine-grained access control,
1591: % such as protected and private methods in objects.
1592: % Third, those operations related to
1593: % distributed programming and fault tolerance,
1594: % such as provided by the \?Connection? and \?Fault? modules.
1595:
1596: \begin{figure}
1597: \figrule
1598: \psfig{file=paradigms3.eps,width=\textwidth}
1599: \caption{Some programming paradigms in Oz.}\label{paradigms}
1600: \figrule
1601: \end{figure}
1602:
1603: \subsection{Multiparadigm programming}
1604: \label{multiparadigm}
1605:
1606: Many different programming styles or ``paradigms'' are possible
1607: by limiting oneself to different subsets of the kernel language.
1608: Some popular styles are object-oriented programming
1609: (programming with state, encapsulation, and inheritance),
1610: functional programming (programming with values and pure functions),
1611: constraint programming (programming with deduction and search),
1612: and sequential programming
1613: (programming with a totally-ordered sequence of instructions).
1614: Some interesting subsets of the kernel language
1615: are shown in Figure~\ref{paradigms}.
1616: The full Oz language provides
1617: syntactic and implementation support that makes
1618: these paradigms and many others equally easy to use.
1619: The execution model is simple and general, which allows
1620: the different styles to coexist comfortably.
1621: This ability is known as {\em multiparadigm} programming.
1622:
1623: The justification of limiting oneself to one particular paradigm
1624: is that the program may be easier to write or reason about.
1625: For example, if the \OzInline{\OzKeyword{thread}} construct is not
1626: used, then the program is purely sequential.
1627: If the \OzInline{ByNeed} operation is not used, then the program is strict.
1628: Experience shows that
1629: different levels of abstraction often need different
1630: paradigms (see Section~\ref{supportmp})~\cite{ftsrparadigm,book}.
1631: Even if the same basic functionality is provided,
1632: it may be useful to view it according to different
1633: paradigms depending on the application needs~\cite{needhamlauer78}.
1634:
1635: How is it possible for such a simple kernel language to
1636: support such different programming styles?
1637: It is because paradigms have many concepts in common,
1638: as Figures~\ref{kernel} and~\ref{paradigms} show.
1639: A good example is sequential object-oriented programming,
1640: which can be built
1641: from the core by adding just state
1642: (see~\cite{opm} for details):
1643: \begin{itemize}
1644: \item Procedures behave as objects when they internally reference state.
1645: \item Methods are different procedures that reference the {\em same} state.
1646: \item Classes are records that group related method definitions.
1647: \item Inheritance is an operation that takes a set
1648: of method definitions and one or more class records,
1649: and constructs a new class record.
1650: \item Creation of new object instances is done by
1651: a higher-order procedure that
1652: takes a class record and associates
1653: a new state pointer with it.
1654: \end{itemize}
1655: Oz has syntactic support to make this style easy to use
1656: and implementation support to make it efficient.
1657: The same applies to the declarative paradigms
1658: of functional and logic programming.
1659: Strict functions are restricted versions of procedures
1660: in which the binding is directional.
1661: Lazy functions are implemented with \OzInline{ByNeed}.
1662:
1663: For logic programming,
1664: procedures become relations when they have
1665: a logical semantics in addition to their
1666: operational semantics.
1667: This is true within the core.
1668: It remains true if one adds concurrency and laziness to the core.
1669: We illustrate the logical semantics
1670: with many examples in this article, starting in Section~\ref{detlp}.
1671: In the core,
1672: the \texttt{if} and \texttt{case} statements have
1673: a logical semantics, i.e., they check entailment and disentailment.
1674: To make the execution {\em complete}, i.e.,
1675: to always find a constructive proof when one exists,
1676: it is necessary to add search.
1677: Oz supports search by means of computation spaces.
1678: When combined with the rest of the model,
1679: they make it possible to program a wide variety
1680: of search algorithms in Oz,
1681: as explained in the next section.
1682:
1683: \subsection{Computation spaces}
1684: \label{compspaces}
1685:
1686: Computation spaces are a powerful abstraction
1687: that permits the high-level programming
1688: of search abstractions and deep guard combinators,
1689: both of which are important for
1690: constraint and logic programming.
1691: Spaces are a natural way to integrate search
1692: into a concurrent system.
1693: Spaces can be implemented efficiently:
1694: on real-world problems
1695: the Mozart 1.1.0 implementation
1696: using copying and recomputation
1697: is competitive in time and memory use
1698: with traditional systems
1699: using trailing-based backtracking~\cite{Schulte:ICLP99}.
1700: Spaces are compositional,
1701: i.e., they can be nested,
1702: which is important for building
1703: well-structured programs.
1704:
1705: % We say that a part of a computation is {\em speculative}
1706: % if the full computation can be exhibited without it.
1707: % A speculative computation is the consequence of a choice
1708: % that leads to a ``dead end''.
1709: % For example, exploration of a part
1710: % of the search space with no solution.
1711: % The full computation can avoid it by making a different choice,
1712: % i.e., deciding not to explore that part of the search space.
1713: % Managing speculative computation
1714: % is the essence of nondeterministic logic programming.
1715:
1716: This section defines computation spaces,
1717: the operations that can be performed on them
1718: (see Figure~\ref{compspacesfig}),
1719: and gives a few examples
1720: of how to use them to program search.
1721: The discussion in this section
1722: follows the model in~\cite{Schulte:02,SchulteDiss:00}.
1723: This model is implemented in Mozart 1.1.0~\cite{mozart110}
1724: and refines the one presented
1725: in the articles~\cite{Engines:97,Schulte:00}.
1726: The space abstraction can be made language-independent;
1727: \cite{figaro-parimplws99} describes a C++ implementation
1728: of a similar abstraction
1729: that supports both trailing and copying.
1730:
1731: \begin{figure}
1732: \figrule
1733: \psfig{file=spaces.eps,width=\textwidth}
1734: \caption{Visibility of variables and bindings in nested spaces.}
1735: \label{spacehierarchy}
1736: \figrule
1737: \end{figure}
1738:
1739: \subsubsection{Definition}
1740:
1741: A computation space is just an Oz store with its four parts.
1742: The store we have seen so far is a single computation space
1743: with equality constraints over rational trees.
1744: To deal with search, we extend this in two ways.
1745: First, we allow spaces to be nested.
1746: Second, we allow other constraint systems in a space.
1747: Since spaces are used to encapsulate
1748: potential variable bindings, it is important
1749: to be precise about the visibility of variables and bindings.
1750: Figure~\ref{spacehierarchy} gives an example.
1751: The general rules
1752: for the structure of computation spaces are as follows:
1753: \begin{itemize}
1754: \item{}There is always a {\em top level} computation space
1755: where threads may interact with the external world.
1756: The top level space is just the store of Section~\ref{store}.
1757: Because the top level space interacts with the external world,
1758: its constraint store always remains consistent, that is,
1759: each variable has at most one binding that never changes
1760: once it is made.
1761: A thread that tries
1762: to add an inconsistent binding
1763: to the top level constraint store
1764: will raise a failure exception.
1765:
1766: \item{}A thread may create a new computation space.
1767: The new space is called a {\em child space}.
1768: The current space is the child's {\em parent space}.
1769: At any time, there is a tree of computation spaces
1770: in which the top level space is the root.
1771: With respect to a given space,
1772: a higher one in the tree (closer to the root)
1773: is called an {\em ancestor} and
1774: a lower one is called a {\em descendant}.
1775:
1776: \item{}A thread always belongs to exactly one computation space.
1777: A variable always belongs to exactly one computation space.
1778:
1779: \item{}A thread sees and may access variables
1780: belonging to its space as well as to all ancestor spaces.
1781: The thread cannot see the variables of descendant spaces.
1782:
1783: \item{}A thread cannot see the variables of a child space,
1784: unless the child space is {\em merged} with its parent.
1785: Space merging is an explicit program operation.
1786: It causes the child space to disappear and all the child's content
1787: to be added to the parent space.
1788:
1789: \item{}A thread may add bindings to variables visible to it.
1790: This means that it may bind variables belonging to its
1791: space or to its ancestor spaces.
1792: The binding will only be visible in
1793: the current space and its descendants.
1794: That is, the parent space does not see the binding unless
1795: the current space is merged with it.
1796:
1797: \item{}If a thread in a child space tries
1798: to add an inconsistent binding to its constraint store,
1799: then the space fails.
1800:
1801: \end{itemize}
1802:
1803: \subsubsection{State of a space}
1804:
1805: A space is {\em runnable} if it or a descendant contains
1806: a runnable thread, and {\em blocked} otherwise.
1807: Let us run all threads in the space and its
1808: descendants, until the space is blocked.
1809: Then the space can be in one of
1810: the following further states:
1811: \begin{itemize}
1812: \item The space is {\em stable}.
1813: This means that no additional
1814: bindings done in an ancestor can make the space runnable.
1815: A stable space can be in four further states:
1816: \begin{itemize}
1817: \item The space is {\em succeeded}.
1818: This means that it contains no choice points.
1819: A succeeded space contains a solution.
1820: % if there are no suspended threads?
1821:
1822: \item The space is {\em distributable}.
1823: This means that the space has one thread
1824: that is suspended on a choice point
1825: with two or more alternatives.
1826: A space can have at most one choice point;
1827: attempting to create another gives a run-time error.
1828:
1829: \item The space is {\em failed}. This is defined
1830: in the previous section; it means that the space
1831: attempted to bind the same variable to two different values.
1832: No further execution happens in the space.
1833:
1834: \item The space is {\em merged}.
1835: This means that the space has been discarded
1836: and its constraint store has been added to its parent.
1837: Any further operation on the space is an error.
1838: This state is the end of a space's lifetime.
1839:
1840: \end{itemize}
1841:
1842: \item The space is {\em suspended}.
1843: This means that additional bindings
1844: done in an ancestor can make the space runnable.
1845: Being suspended is usually a temporary condition
1846: due to concurrency.
1847: It means that some ancestor space has not yet
1848: transferred all required information to the space.
1849: A space that stays suspended indefinitely
1850: usually indicates a programmer error.
1851: \end{itemize}
1852:
1853: \subsubsection{Programming search}
1854: \label{spaceops}
1855:
1856: A {\em search strategy} defines how the search tree is explored,
1857: e.g., depth-first seach, limited discrepancy search,
1858: best-first search, and branch-and-bound search.
1859: A {\em distribution strategy} defines
1860: the shape and content of the search tree,
1861: i.e., how many alternatives exist at a node and
1862: what constraint is added for each alternative.
1863: Computation spaces can be used to program
1864: search strategies and distribution strategies
1865: independent of each other.
1866: That is, any search strategy can be used together
1867: with any distribution strategy.
1868: Here is how it is done:
1869: \begin{itemize}
1870: \item Create the space and initialize it
1871: by running an internal program that defines all
1872: the variables and constraints in the space.
1873:
1874: \item Propagate information inside the space.
1875: The constraints in a space have an operational semantics.
1876: In Oz terminology, an operationalized version of
1877: a constraint is called a {\em propagator}.
1878: Propagators execute concurrently; each propagator
1879: executes inside its own thread.
1880: Each propagator reads its arguments and attempts to add
1881: information to the constraint store by restricting
1882: the domains of its arguments.
1883:
1884: \item All propagators execute until no more information
1885: can be added to the store in this manner.
1886: This is a fixpoint calculation.
1887: When no more information can be added,
1888: then the fixpoint is reached and
1889: the space has become stable.
1890:
1891: \item During a space's execution,
1892: the computation inside the space
1893: can decide to create a choice point.
1894: The decision which constraint to add
1895: for each alternative defines the distribution strategy.
1896: One of the space's threads will suspend when
1897: the choice point is created.
1898:
1899: \item When the space has become stable,
1900: then execution continues outside the space,
1901: to decide what to do next.
1902: There are different possibilities depending on whether or not
1903: a choice point has been created in the space.
1904: If there is none, then execution can stop and return with a solution.
1905: If there is one,
1906: then the search strategy decides which alternative
1907: to choose and commits to that alternative.
1908: \end{itemize}
1909: Notice that the distribution strategy is problem-dependent:
1910: to add a constraint we need to know the problem's constraints.
1911: On the other hand,
1912: the search strategy is problem-independent:
1913: to pick an alternative we do not need to know
1914: which constraint it corresponds to.
1915: The next section explains
1916: the operations we need to implement this approach.
1917: Then, Section~\ref{spaceexamples}
1918: gives some examples of how to program search.
1919:
1920: \begin{figure}
1921: \figrule
1922: \begin{center}
1923: \begin{tabular}{lrl}
1924: \multicolumn{2}{l}{\nt{space} ::=}
1925: & \OzInline{\OzChar\{NewSpace} \nt{x} \nt{y}\OzInline{\OzChar\}} \\
1926: & $|$ & \OzInline{\OzChar\{Choose} \nt{x} \nt{y}\OzInline{\OzChar\}} \\
1927: & $|$ & \OzInline{\OzChar\{Ask} \nt{x} \nt{y}\OzInline{\OzChar\}} \\
1928: & $|$ & \OzInline{\OzChar\{Commit} \nt{x} \nt{y}\OzInline{\OzChar\}} \\
1929: & $|$ & \OzInline{\OzChar\{Clone} \nt{x} \nt{y}\OzInline{\OzChar\}} \\
1930: & $|$ & \OzInline{\OzChar\{Inject} \nt{x} \nt{y}\OzInline{\OzChar\}} \\
1931: & $|$ & \OzInline{\OzChar\{Merge} \nt{x} \nt{y}\OzInline{\OzChar\}}
1932: \end{tabular}
1933: \end{center}
1934: \caption{Primitive operations for computation spaces.}
1935: \label{compspacesfig}
1936: \figrule
1937: \end{figure}
1938:
1939: \subsubsection{Space operations}
1940:
1941: Now we know enough to define the primitive space operations.
1942: There are seven principal ones (see Figure~\ref{compspacesfig}).
1943: \begin{itemize}
1944: \item \OzInline{\OzChar\{NewSpace\OzSpace{1}P\OzSpace{1}X\OzChar\}}, when given a unary
1945: procedure \OzInline{P}, creates a new computation space \OzInline{X}.
1946: In this space, a fresh variable \OzInline{R}, called the
1947: {\em root variable}, is created,
1948: and \OzInline{\OzChar\{P\OzSpace{1}R\OzChar\}} is invoked in a new thread.
1949:
1950: \item \OzInline{\OzChar\{Choose\OzSpace{1}N\OzSpace{1}Y\OzChar\}} is the only operation
1951: that executes {\em inside} a space.
1952: It creates a choice point with \OzInline{N} alternatives.
1953: Then it blocks, waiting for an alternative to be chosen
1954: by a \OzInline{Commit} operation on the space (see below).
1955: The \OzInline{Choose} call defines only the {\em number} of
1956: alternatives; it does not
1957: specify what to do for any given alternative.
1958: \OzInline{Choose} returns with \OzInline{Y=I} when
1959: alternative \OzInline{1}$\leq$\OzInline{I}$\leq$\OzInline{N} is chosen.
1960: A maximum of one choice point
1961: may exist in a space at any time.
1962: % With just one alternative, \?Choose? is defined to allow
1963: % to synchronize on stability.
1964:
1965: \item \OzInline{\OzChar\{Ask\OzSpace{1}X\OzSpace{1}A\OzChar\}} asks the space \OzInline{X} for its status.
1966: As soon as the space becomes stable, \OzInline{A} is bound.
1967: If \OzInline{X} is failed, merged, or succeeded,
1968: then \OzInline{A} is bound to \OzInline{failed}, \OzInline{merged}, or \OzInline{succeeded}.
1969: If \OzInline{X} is distributable, then \OzInline{A=alternatives(N)},
1970: where \OzInline{N} is the number of alternatives.
1971:
1972: \item \OzInline{\OzChar\{Commit\OzSpace{1}X\OzSpace{1}I\OzChar\}}, if \OzInline{X} is a distributable space,
1973: causes the blocked \OzInline{Choose} call in the space to continue
1974: with \OzInline{I} as its result.
1975: This may cause a stable space to become not stable again.
1976: The space will resume execution until a new fixpoint is reached.
1977: The integer \OzInline{I} must satisfy \OzInline{1}$\leq$\OzInline{I}$\leq$\OzInline{N},
1978: where \OzInline{N} is the first argument of the \OzInline{Choose} call.
1979:
1980: \item \OzInline{\OzChar\{Clone\OzSpace{1}X\OzSpace{1}C\OzChar\}}, if \OzInline{X} is a stable space,
1981: creates an identical copy (a {\em clone}) of \OzInline{X} in \OzInline{C}.
1982: This allows the alternatives of a distributable space to
1983: be explored independently.
1984:
1985: \item \OzInline{\OzChar\{Inject\OzSpace{1}X\OzSpace{1}P\OzChar\}} is similar to space creation
1986: except that it uses an existing space \OzInline{X}.
1987: It creates a new thread in the space
1988: and invokes \OzInline{\OzChar\{P\OzSpace{1}R\OzChar\}} in the thread,
1989: where \OzInline{R} is the space's root variable.
1990: This may cause a stable space to become not stable again.
1991: The space will resume execution until a new fixpoint is reached.
1992: Adding constraints to an existing space is necessary
1993: for some search strategies such as branch-and-bound
1994: and saturation.
1995:
1996: \item \OzInline{\OzChar\{Merge\OzSpace{1}X\OzSpace{1}Y\OzChar\}} binds \OzInline{Y} to the
1997: root variable of space \OzInline{X} and discards the space.
1998:
1999: \end{itemize}
2000:
2001: \begin{figure}
2002: \figrule
2003: \psfig{file=spacesynch.eps,width=\textwidth}
2004: \caption{Communication between a space and its search strategy.}
2005: \label{spacesynch}
2006: \figrule
2007: \end{figure}
2008:
2009: \subsubsection{Using spaces}
2010: \label{spaceexamples}
2011:
2012: These seven primitive operations are enough to
2013: define many search strategies and distribution strategies.
2014: The basic technique is to use \OzInline{Choose}, \OzInline{Ask},
2015: and \OzInline{Commit} to communicate between
2016: the inside of the space and the outside of the space.
2017: Figure~\ref{spacesynch} shows how the communication
2018: works: first the space informs the search strategy
2019: of the total number of alternatives (\OzInline{N}).
2020: Then the search strategy picks one (\OzInline{I}) and
2021: informs the space.
2022: Let us now present briefly a few examples of how to use spaces.
2023: For complete information on these examples
2024: and many other examples we refer the reader
2025: to~\cite{Schulte:02,SchulteDiss:00}.
2026:
2027: \paragraph{Depth-first search.}
2028:
2029: Our first example implements a search strategy.
2030: Figure~\ref{DFS} shows how to program
2031: depth-first single solution search
2032: in the case of binary choice points.
2033: This explores the search tree in depth-first
2034: manner and returns the first solution it finds.
2035: The problem is defined as a unary procedure \OzInline{\OzChar\{P\OzSpace{1}Sol\OzChar\}}
2036: that gives a reference to the solution \OzInline{Sol},
2037: just like the example in Section~\ref{scalable}.
2038: The solution is returned
2039: in a one-element list as \OzInline{[Sol]}.
2040: If there is no solution, then \OzInline{nil} is returned.
2041: In \OzInline{P}, choice points are defined with the \OzInline{Choose} operation.
2042:
2043: \begin{figure}
2044: \figrule
2045: \begin{center}
2046: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{fun}\OzSpace{1}\OzChar\{DFE\OzSpace{1}S\OzChar\}\OzEol
2047: \OzSpace{6}\OzKeyword{case}\OzSpace{1}\OzChar\{Ask\OzSpace{1}S\OzChar\}\OzEol
2048: \OzSpace{6}\OzKeyword{of}\OzSpace{1}failed\OzSpace{1}\OzKeyword{then}\OzSpace{1}nil\OzEol
2049: \OzSpace{6}[]\OzSpace{1}succeeded\OzSpace{1}\OzKeyword{then}\OzSpace{1}[S]\OzEol
2050: \OzSpace{6}[]\OzSpace{1}alternatives(2)\OzSpace{1}\OzKeyword{then}\OzSpace{1}C=\OzChar\{Clone\OzSpace{1}S\OzChar\}\OzSpace{1}\OzKeyword{in}\OzEol
2051: \OzSpace{9}\OzChar\{Commit\OzSpace{1}S\OzSpace{1}1\OzChar\}\OzEol
2052: \OzSpace{9}\OzKeyword{case}\OzSpace{1}\OzChar\{DFE\OzSpace{1}S\OzChar\}\OzSpace{1}\OzKeyword{of}\OzSpace{1}nil\OzSpace{1}\OzKeyword{then}\OzSpace{1}\OzChar\{Commit\OzSpace{1}C\OzSpace{1}2\OzChar\}\OzSpace{1}\OzChar\{DFE\OzSpace{1}C\OzChar\}\OzEol
2053: \OzSpace{9}[]\OzSpace{1}[T]\OzSpace{1}\OzKeyword{then}\OzSpace{1}[T]\OzEol
2054: \OzSpace{9}\OzKeyword{end}\OzEol
2055: \OzSpace{6}\OzKeyword{end}\OzEol
2056: \OzSpace{3}\OzKeyword{end}\OzEol
2057: \OzEol
2058: \OzSpace{3}\OzEolComment{\OzSpace{1}Given\OzSpace{1}procedure\OzSpace{1}\OzChar\{P\OzSpace{1}Sol\OzChar\},\OzSpace{1}returns\OzSpace{1}solution\OzSpace{1}[Sol]\OzSpace{1}or\OzSpace{1}nil:}\OzSpace{3}\OzKeyword{fun}\OzSpace{1}\OzChar\{DFS\OzSpace{1}P\OzChar\}\OzEol
2059: \OzSpace{6}\OzKeyword{case}\OzSpace{1}\OzChar\{DFE\OzSpace{1}\OzChar\{NewSpace\OzSpace{1}P\OzChar\}\OzChar\}\OzSpace{1}\OzKeyword{of}\OzSpace{1}nil\OzSpace{1}\OzKeyword{then}\OzSpace{1}nil\OzEol
2060: \OzSpace{6}[]\OzSpace{1}[S]\OzSpace{1}\OzKeyword{then}\OzSpace{1}[\OzChar\{Merge\OzSpace{1}S\OzChar\}]\OzEol
2061: \OzSpace{6}\OzKeyword{end}\OzEol
2062: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
2063: \end{center}
2064: \caption{Depth-first single solution search.}
2065: \label{DFS}
2066: \figrule
2067: \end{figure}
2068:
2069: \paragraph{Naive choice point.}
2070:
2071: Our second example implements a distribution strategy.
2072: Let us implement a naive choice point,
2073: namely one that defines a set of alternative statements
2074: to be chosen.
2075: This can be defined as follows:
2076: \newpage
2077: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{case}\OzSpace{1}\OzChar\{Choose\OzSpace{1}N\OzChar\}\OzEol
2078: \OzSpace{3}\OzKeyword{of}\OzSpace{1}1\OzSpace{1}\OzKeyword{then}\OzSpace{1}$S_1$\OzEol
2079: \OzSpace{3}[]\OzSpace{1}2\OzSpace{1}\OzKeyword{then}\OzSpace{1}$S_2$\OzEol
2080: \OzSpace{3}...\OzEol
2081: \OzSpace{3}[]\OzSpace{1}N\OzSpace{1}\OzKeyword{then}\OzSpace{1}$S_n$\OzEol
2082: \OzSpace{3}\OzKeyword{end}\end{oz2texdisplay}
2083: Oz provides the following more convenient syntax
2084: for this technique:
2085: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{choice}\OzSpace{1}$S_1$\OzSpace{1}[]\OzSpace{1}...\OzSpace{1}[]\OzSpace{1}$S_n$\OzSpace{1}\OzKeyword{end}\end{oz2texdisplay}
2086: % \begin{center}
2087: % \begin{tabular}{l}
2088: % \texttt{choice}
2089: % ~{\normalfont\ensuremath{\langle\textsf{S${}_1$}\rangle}}~
2090: % \ZCHAR{\[}\ZCHAR{\]}
2091: % ~{\normalfont\ensuremath{\langle\textsf{S${}_2$}\rangle}}~
2092: % \ZCHAR{\[}\ZCHAR{\]}~...~\ZCHAR{\[}\ZCHAR{\]}
2093: % ~{\normalfont\ensuremath{\langle\textsf{S${}_n$}\rangle}}~
2094: % \texttt{end}
2095: % \end{tabular}
2096: % \end{center}
2097: This is exactly how the \OzInline{\OzKeyword{choice}} statement is defined.
2098: This statement can be used with any search strategy,
2099: such as the depth-first strategy we defined previously
2100: or other strategies.
2101:
2102: \paragraph{Andorra-style disjunction (the \OzInline{\OzKeyword{dis}} statement).}
2103: \label{andorradis}
2104:
2105: Let us now define a slightly more complex distribution strategy.
2106: We define the \OzInline{\OzKeyword{dis}} statement, which is an extension of \OzInline{\OzKeyword{choice}} that
2107: eliminates failed alternatives and commits
2108: immediately if there is a single remaining alternative:
2109: \begin{oz2texdisplay}\OzSpace{3}\OzKeyword{dis}\OzSpace{1}$G_1$\OzSpace{1}\OzKeyword{then}\OzSpace{1}$S_1$\OzSpace{1}[]\OzSpace{1}...\OzSpace{1}[]\OzSpace{1}$G_n$\OzSpace{1}\OzKeyword{then}\OzSpace{1}$S_n$\OzSpace{1}\OzKeyword{end}\end{oz2texdisplay}
2110: In contrast to \OzInline{\OzKeyword{choice}}, each alternative of a \OzInline{\OzKeyword{dis}} statement
2111: has both a guard and a body.
2112: The guards are used immediately to check failure.
2113: If a guard $G_i$ fails then its alternative is eliminated.
2114: This extension is sometimes called determinacy-directed execution.
2115: It was discovered by D.H.D. Warren
2116: and called the {\em Andorra principle}~\cite{andorra,andorramodel}.
2117:
2118: The \OzInline{\OzKeyword{dis}} statement can be
2119: programmed with the space operations as follows.
2120: First encapsulate each guard
2121: of the \OzInline{\OzKeyword{dis}} statement in a separate space.
2122: Then execute each guard until it is stable.
2123: Discard all failed guards.
2124: Finally, using the \OzInline{Choose} operation,
2125: create a choice point for the remaining guards.
2126: See~\cite{Schulte:02,SchulteDiss:00} for details of the implementation.
2127: It can be optimized to do first-argument indexing
2128: in a similar way to Prolog systems.
2129: We emphasize that
2130: the whole implementation is written within the language.
2131:
2132: \paragraph{The first-fail strategy.}
2133:
2134: In practice, \OzInline{\OzKeyword{dis}} is not strong enough for solving
2135: real constraint problems.
2136: It is too static: its alternatives are
2137: defined textually in the program code.
2138: A more sophisticated distribution strategy would
2139: look more closely at the actual state of the execution.
2140: For example, the {\em first-fail} strategy
2141: for finite domain constraints
2142: looks at all variables and places a choice
2143: point on the variable whose domain is the smallest.
2144: First-fail can be implemented with \OzInline{Choose}
2145: and a set of reflective operations on finite domain constraints.
2146: The Mozart system provides first-fail
2147: as one of many preprogrammed strategies.
2148:
2149: \paragraph{Deep guard combinators.}
2150:
2151: A {\em constraint combinator} is an operator that takes
2152: constraints as arguments and combines them to form another constraint.
2153: Spaces are a powerful way to implement constraint combinators.
2154: Since spaces are compositional, the resulting constraints
2155: can themselves be used as inputs to other constraint combinators.
2156: For this reason,
2157: these combinators are called {\em deep guard} combinators.
2158: This is more powerful than other techniques, such as reification,
2159: which are {\em flat}: their input constraints are limited to
2160: simple combinations of built-in constraints.
2161: Some examples of deep guard combinators
2162: that we can program are deep negation,
2163: generalized reification,
2164: propagation-based disjunction (such as \OzInline{\OzKeyword{dis}}),
2165: constructive disjunction,
2166: and deep committed-choice.
2167:
2168: \section{Related work}
2169: \label{related}
2170:
2171: We first give a brief overview of research
2172: in the area of multiparadigm programming.
2173: We then give a short history of Oz.
2174:
2175: \subsection{Multiparadigm languages}
2176:
2177: % ? Summarize Mercury: adds functional programming abilities,
2178: % types, and modes to Prolog.
2179:
2180: % ? Summarize CIAO: adds concurrency, functional? abilities
2181: % to Prolog.
2182:
2183: Integration of paradigms is an active area of research
2184: that has produced a variety of different languages.
2185: We give a brief glimpse into this area.
2186: We do not pretend to be exhaustive; that would
2187: be the subject of another paper.
2188: As far as we know, there is no other language
2189: that covers as many paradigms as Oz
2190: in an equitable way, i.e.,
2191: with a simple formal semantics~\cite{kerneloz,book}
2192: and an efficient implementation~\cite{amoz,Mehl:diss,ScheidhauerDiss,Schulte:02,SchulteDiss:00}.
2193: An early discussion of multiparadigm programming in Oz
2194: is given in~\cite{elephant}.
2195: It gives examples in functional, logic, and object-oriented styles.
2196:
2197: A short-term solution to integrate different paradigms is to use
2198: a {\em coordination model}~\cite{CarrieroGelernter:89,linda}.
2199: The prototypical coordination model is Linda,
2200: which provides a uniform global tuple space that
2201: can be accessed with a small set of
2202: basic operations (concurrent reads and writes)
2203: from any process that is connected to it.
2204: A Linda layer can act as ``glue'' between
2205: languages of different paradigms.
2206: Let us now look at more substantive solutions.
2207:
2208: % Within the imperative paradigm,
2209: % typed imperative languages (e.g., Algol, Eiffel, C++, or Java) may
2210: % be viewed as adding a level of stateless
2211: % semantics to a possibly stateful program.
2212: % They do not, however, provide for stateless {\em programming}.
2213:
2214: Within the imperative paradigm,
2215: there have been several efforts to add the abilities
2216: of functional programming.
2217: Smalltalk has ``blocks'',
2218: which are lexically-scoped closures~\cite{smalltalk80}.
2219: Java has inner classes, which (with minor limitations)
2220: are lexically-scoped closures.
2221: Java supports the {\tt final} annotation, which
2222: allows programming with stateless objects.
2223: Using inner classes and {\tt final} allows
2224: to do functional programming in Java.
2225: However, this technique is verbose and its use
2226: is discouraged~\cite{javabook}.
2227: More ambitious efforts are
2228: C++ libraries such as FC++~\cite{fc}
2229: and language extensions
2230: such as Pizza~\cite{pizza} and Brew~\cite{brew},
2231: which translate into Java.
2232: These provide much better support for functional programming.
2233:
2234: Within the functional paradigm,
2235: the easiest way to allow imperative programming
2236: is to add locations with destructive assignment.
2237: This route was taken by languages such as
2238: Lisp \cite{commonlisp}, Scheme \cite{R4RS:91},
2239: and SML \cite{HarperMacQueenMilner:86}.
2240: The M-structures of Id \cite{Nikhil:Id:91} and its
2241: successor pH \cite{Nikhil:pH:94,ph} fall in this category as well.
2242: Objective Caml is a popular object-oriented dialect of ML
2243: that takes this approach~\cite{ocaml,ocaml2}.
2244: Oz also takes this approach, building an object system
2245: from a functional core by adding
2246: the cell as its location primitive.
2247:
2248: In Haskell, state is integrated using the monadic style of
2249: programming \cite{Wadler:92c,PeytonJonesWadler:93} which
2250: generalizes the continuation-passing style.
2251: Because Haskell is a nonstrict language,
2252: it cannot easily add locations with destructive assignment.
2253: The monadic style allows to control the sequentialization
2254: necessary for various kinds of side effecting
2255: (I/O, error handling, nondeterministic choice).
2256: However, because it imposes a global state threading,
2257: it has difficulties when integrated with concurrency.
2258: See~\cite{book} for a discussion of the relative
2259: merits of the state threading approach versus
2260: the location approach.
2261:
2262: Within the logic paradigm,
2263: there have been many attempts
2264: to add an object system~\cite{Davison:93}.
2265: Prominent examples are Prolog++~\cite{moss}
2266: and SICStus Objects~\cite{sicstus}.
2267: These approaches use locations as primitives,
2268: much like the functional approach.
2269:
2270: Functions have been added in several ways to logic languages.
2271: A first approach is LIFE, which
2272: provides functions as a kind of relation
2273: that is called by {\em entailment},
2274: i.e, the function call waits
2275: until its arguments have enough information.
2276: This delaying mechanism is called {\em residuation}~\cite{life89,jlplife,Ait-Kaci+Lincoln/88/LIFE,wildlife-handbook}.
2277: A second approach extends the basic resolution step
2278: to include the deterministic evaluation of functions.
2279: This execution strategy, called {\em narrowing},
2280: underlies the Curry language~\cite{Hanus:JLP:94,curry}.
2281: A third approach is taken by
2282: Lambda Prolog~\cite{NadathurMiller:95}\nocite{GabbayHoggerRobinson:95}.
2283: It uses a more powerful logic than Horn logic as a basis for programming.
2284: In particular, functional programming is supported
2285: by providing $\lambda$ terms as data structures, which are handled
2286: by a form of higher-order unification.
2287: A fourth approach is taken by HiLog~\cite{hilog},
2288: which introduces a higher-order syntax that can be encoded
2289: into the first-order predicate calculus.
2290:
2291: The Oz approach is to provide first-class procedure values
2292: and to consider them as constants for the purposes of unification.
2293: This approach cleanly separates the logical aspects
2294: from the higher-order programming aspects.
2295: All the other approaches mentioned
2296: are more closely tied to the resolution operation.
2297: In addition, the Oz approach provides the full power
2298: of lexically-scoped closures as values in the language.
2299: Finally, Oz provides entailment checking as a separate operation,
2300: which allows it to implement call by entailment.
2301:
2302: Erlang is a notable example of a multiparadigm language.
2303: It has a layered design~\cite{erlang,derlang}.
2304: Erlang programs consist of active objects that send messages to each other.
2305: A strict functional language
2306: is used to program the internals of the active objects.
2307: Each active object contains one thread that runs a recursive function.
2308: The object state is contained in the function arguments.
2309: This model is extended further with distribution
2310: and fault tolerance.
2311:
2312: The layered approach is also taken by pH,
2313: a language designed for defining algorithms
2314: with implicit parallelism~\cite{Nikhil:pH:94,ph}.
2315: Its core is based on Haskell.
2316: It has two extensions.
2317: The first extension is a single-assignment data type, I-structures.
2318: This allows to write functional programs that have dataflow behavior.
2319: The second extension is a mutable data type, M-structures.
2320: This allows stateful programs.
2321: This design has similarities to Oz,
2322: with logic variables being the single-assignment extension
2323: and cells the mutable extension.
2324:
2325: Concurrent logic programming has investigated in depth the use
2326: of logic variables for synchronization and communication.
2327: They are one of the most expressive mechanisms for
2328: practical concurrent programming~\cite{BalSteinerTanenbaum:89,book}.
2329: Since logic variables are constrained monotonically,
2330: they can express monotonic synchronization.
2331: This allows declarative concurrency,
2332: which is concurrent programming with no observable nondeterminism.
2333: The concurrent logic language Strand evolved into
2334: the coordination language
2335: PCN \cite{Foster:PCN-Strand:93} for imperative languages.
2336: In the functional programming community,
2337: the futures of Multilisp~\cite{halstead}
2338: and the I-structures of Id~\cite{Nikhil:Id:91}
2339: allow to synchronize on the result of a concurrent computation.
2340: Both realize a restricted form of logic variable.
2341: Finally, the Goffin project~\cite{ChakravartyEtAl:95}
2342: uses a first-order concurrent constraint language as
2343: a coordination language for Haskell processes.
2344:
2345: % The logic language G\"odel \cite{HillLloyd:94} aims at
2346: % being a more declarative Prolog.
2347: % It provides for a strong type system and a module system.
2348: % The control facilities provided
2349: % by G\"odel allow for coroutining, a pruning (or commit) operator
2350: % related to parallel conditionals in concurrent Prolog, and
2351: % constraint solving capabilities in the domains of integers and
2352: % rationals.
2353:
2354: The multiparadigm language Leda
2355: was developed for educational purposes~\cite{leda}.
2356: It is sequential, supports
2357: functional and object-oriented programming,
2358: and has basic support for backtracking and a simple
2359: form of logic programming that is a subset of Prolog.
2360:
2361: \begin{figure}
2362: \figrule
2363: \psfig{file=history_art.eps,width=\textwidth}
2364: \caption{History of Oz.}
2365: \label{history}
2366: \figrule
2367: \end{figure}
2368:
2369: \subsection{History of Oz}
2370: \label{historysketch}
2371:
2372: Oz is a recent descendant of a long line of logic-based languages
2373: that originated with Prolog
2374: (see Figure~\ref{history}).
2375: We summarize briefly the evolutionary path
2376: and give some of the important milestones along the way.
2377: First experiments with concurrency were done
2378: in the venerable IC-Prolog language
2379: where coroutining was used
2380: to simulate concurrent processes~\cite{CM79:,Clar82a}.
2381: This led to Parlog and Concurrent Prolog, which introduced the process model
2382: of logic programming, usually known as
2383: {\em concurrent} logic programming~\cite{lncs259*30,tr003,concprolog}.
2384: The advent of GHC (Guarded Horn Clauses) simplified
2385: concurrent logic programming considerably by introducing the notion of
2386: {\em quiet guards}~\cite{lncs221*168}.
2387: A clause matching a goal will fire only if the guard is
2388: entailed by the constraint store.
2389: This formulation and its theoretical
2390: underpinning were pioneered by the work of
2391: Maher and Saraswat as they gave a solid foundation
2392: to concurrent logic programming~\cite{maher87,saraswat90,SaraswatBook}.
2393: The main insight is that logical notions such as
2394: equality and entailment can be given an operational reading.
2395: Saraswat's concurrent constraint model
2396: is a model of concurrent programming with a logical foundation.
2397: This model was subsequently used as the basis
2398: for several languages including AKL and Oz.
2399:
2400: On the practical side, systems with ``flat'' guards
2401: (which are limited to basic constraints or system-provided tests)
2402: were the focus of much work~\cite{deevolution}.
2403: The flat versions of Concurrent Prolog and GHC,
2404: called FCP and FGHC respectively,
2405: were developed into large systems~\cite{fgcs92,Shapiro:89}.
2406: The KL1 (Kernel Language 1) language, derived from FGHC, was implemented
2407: in the high-performance KLIC system.
2408: This system runs on
2409: sequential, parallel, and distributed machines~\cite{klic}.
2410: Some of the implementation techniques in the current Mozart system
2411: were inspired by KLIC,
2412: notably the distributed garbage collection algorithm.
2413:
2414: An important subsequent development
2415: was AKL (Andorra Kernel Language)~\cite{janson91,sverkerthesis,portpaper},
2416: which added state (in the form of ports),
2417: encapsulated search,
2418: and an efficient implementation of deep guards.
2419: AKL is the first language that combines the
2420: abilities of constraint logic programming
2421: and concurrent logic programming.
2422: AKL implements encapsulated search
2423: using a precursor of computation spaces.
2424: When local propagation within a space
2425: cannot choose between different disjuncts,
2426: then the program can try each disjunct by cloning the computation space.
2427:
2428: The initial Oz language, Oz 1,
2429: was inspired by AKL and LIFE, and added higher-order procedures,
2430: programmable search based on the solve combinator
2431: (a less expressive precursor of
2432: spaces~\cite{SchulteSmolkaEa:94,SchulteSmolka:94}),
2433: compositional syntax,
2434: and the cell primitive for mutable state~\cite{opm}.
2435: Oz 1 features a new record data type
2436: that was inspired by LIFE~\cite{SmolkaTreinen:94b,VMS:PLILP96}.
2437: Concurrency in Oz 1 is implicit and based on lazy thread creation.
2438: When a statement blocks, a new thread
2439: is created that contains only the blocked statement.
2440: The main thread is not suspended but
2441: continues with the next statement.
2442: Oz 1 features a concurrent
2443: object system designed for lazy thread creation,
2444: based on state threading and monitors.
2445:
2446: Oz 2 improves on its predecessor Oz 1
2447: with an improved concurrency model
2448: and an improved model for encapsulated search.
2449: Oz 2 replaces the solve combinator of Oz 1
2450: by computation spaces.
2451: In contrast to the solve combinator,
2452: spaces allow programming important search strategies
2453: such as parallel search, the Oz Explorer,
2454: and strategies based on recomputation.
2455: Oz 2 abandons implicit concurrency
2456: in favor of an explicit thread creation construct.
2457: Thread suspension and resumption are still
2458: based on dataflow using logic variables.
2459: Our experience shows
2460: that explicit concurrency makes it easier
2461: for the user to control application resources.
2462: It allows the language to have an efficient and expressive
2463: object system without
2464: sequential state threading in method definitions.
2465: It allows a simple debugging model and
2466: it makes it easy to add exception handling to the language.
2467:
2468: The current Oz language, Oz 3, conservatively extends Oz 2 with
2469: support for first-class module specifications,
2470: called {\em functors}~\cite{modules-98},
2471: and for open, robust, distributed
2472: programming~\cite{ngc98,dstutorial,toplas99,sendai99,perdio}.
2473: A functor specifies a module in terms of the other modules it needs.
2474: Distribution is transparent, i.e.,
2475: the language semantics is unchanged
2476: independent of how the program is distributed.
2477: With respect to logic programming, the distributed
2478: extension has two properties:
2479: \begin{itemize}
2480: \item The top level space
2481: is efficiently distributed over multiple processes.
2482: In particular, the top level store
2483: is implemented by a practical algorithm for
2484: distributed rational tree unification~\cite{toplas99}.
2485: \item A child computation space is a stationary entity
2486: that exists completely in one process.
2487: Due to the communication overheads involved,
2488: we have not found it worthwhile to distribute
2489: one child space over multiple processes.
2490: Constraint propagation {\em within} a child space
2491: is therefore completely centralized.
2492: Parallel search engines (see example in Section~\ref{scalable})
2493: are implemented by putting
2494: child spaces in different processes.
2495: \end{itemize}
2496: In all versions of Oz, concurrency is intended primarily
2497: to model logical concurrency in the application
2498: rather than to achieve parallelism (speedup) in the implementation.
2499: However, the distributed implementation is
2500: useful for parallel execution.
2501: It is optimized to be
2502: particularly efficient on shared-memory multiprocessors.
2503: For that case,
2504: we have experimented with an implementation
2505: of interprocess communication
2506: using shared pages between address spaces~\cite{ngc98}.
2507:
2508: \section{Lessons learned}
2509: \label{lessons}
2510:
2511: One of the goals of the Oz project was to use logic programming
2512: for real-world problems.
2513: During the course of the project, we have tried out many
2514: implementations and programming techniques, and built many applications.
2515: From this experience, we have learned many lessons
2516: both for practical logic programming and
2517: for multiparadigm programming.
2518: Here is a summary of the most important of these lessons.
2519: We agree with the conclusions of Hughes, namely that
2520: higher-order procedures are essential and
2521: that laziness (demand-driven execution) is useful~\cite{fpmatters}.
2522:
2523: \subsection{Be explicit (``magic'' does not work)}
2524:
2525: \begin{itemize}
2526: \item Provide explicit concurrency
2527: (older concurrent logic programming systems have implicit concurrency).
2528: This is
2529: important for interaction with the environment, efficiency, facilitating
2530: reasoning (e.g., for termination), and debugging.
2531: It is also important for distributed programming.
2532:
2533: \item Provide explicit search (Prolog has implicit search).
2534: The majority of
2535: Prolog programs solve algorithmic problems,
2536: which do not need search, yet one cannot
2537: use Prolog without learning about search.
2538: Furthermore, for search problems
2539: the search must be {\em very} controllable,
2540: otherwise it does not scale to real applications.
2541: Prolog's implicit search is much too weak;
2542: this means that inefficient approaches such as
2543: meta-interpreters are needed.
2544: We conclude that Prolog's search is ineffective for
2545: both algorithmic and search problems.
2546:
2547: \item Provide explicit state (in C++ and Java, state is implicit,
2548: e.g., Java variables are stateful unless declared {\tt final}).
2549: By explicit state we mean that the language should declare
2550: mutable references only where they are needed.
2551: Explicit state should be used sparingly,
2552: since it complicates reasoning about programs
2553: and is costly to implement in a distributed system.
2554: On the other hand,
2555: explicit state is crucial for modularity, i.e., the ability
2556: to change a program component without having
2557: to change other components.
2558:
2559: \item Provide explicit laziness
2560: (in Haskell, laziness is implicit for all functions).
2561: Explicitly declaring functions as lazy makes them easy to implement
2562: and documents the programmer's intention.
2563: This allows the system to pay for laziness only where it is used.
2564: A second reason is declarative concurrency:
2565: supporting it well requires eager as well as lazy functions.
2566: A third reason is explicit state.
2567: With implicit laziness (and a fortiori with nonstrictness),
2568: it is harder to reason about
2569: functions that use explicit state.
2570: This is because the order of function evaluation
2571: is not determined by syntax but is data dependent.
2572:
2573: \end{itemize}
2574:
2575: \subsection{Provide primitives for building abstractions}
2576:
2577: \begin{itemize}
2578: \item Full compositionality is essential:
2579: everything can be nested everywhere.
2580: For maximum usefulness,
2581: this requires higher-order procedures with lexical scoping.
2582: User-defined abstractions should be carefully designed
2583: to be fully compositional.
2584:
2585: \item The language should be complete enough so
2586: that it is easy to define new abstractions.
2587: The developer should have all the primitives necessary
2588: to build powerful abstractions.
2589: For example, in addition to lexical scoping, it is
2590: important to have {\em read-only} logic variables,
2591: which allow to build abstractions that export
2592: logic variables and still protect them~\cite{futures}.
2593: There is no distinction between built-in abstractions and
2594: application-specific ones, except possibly regarding performance.
2595: Examples of built-in abstractions are the object system,
2596: reentrant locks, distribution support, and user interface support.
2597: \end{itemize}
2598:
2599: \subsection{Factorize and be lean}
2600:
2601: Complexity is a source of problems and
2602: must be reduced as much as possible:
2603: \begin{itemize}
2604: \item Factorize the design at {\em all} levels of abstraction,
2605: both in the language and the implementation.
2606: Keep the number of primitive operations to a minimum.
2607: This goal is often in conflict with the goal of
2608: having an efficient implementation.
2609: Satisfying both is difficult, but sometimes possible.
2610: One approach that helps is to have a second kernel language,
2611: as explained in Section~\ref{kernellang}.
2612: Another approach is ``loosening and tightening''.
2613: That is, develop the system in semi-independent stages,
2614: where one stage is factored and the next stage brings the factors together.
2615: A typical example is a compiler consisting of
2616: a naive code generator followed by a smart peephole optimizer.
2617:
2618: \item It is important to have a sophisticated module system,
2619: with lazy loading, support for mutually-dependent modules,
2620: and support for application deployment.
2621: In Mozart, both Oz and C++ modules can be loaded lazily,
2622: i.e., only when the module is needed.
2623: In this way, the system is both lean and
2624: has lots of functionality.
2625: Lazy loading of Oz modules is implemented with the
2626: \OzInline{ByNeed} operation (see Section~\ref{kernellang}).
2627: Support for mutually-dependent Oz modules means that cyclic
2628: dependencies need to bottom out only at run-time, not at load-time.
2629: This turns out to be important in practice, since modules
2630: often depend on each other.
2631: Support for application deployment
2632: includes the ability to statically link
2633: a collection of modules into a single module.
2634: This simplifies how modules are offered to users.
2635: A final point is that the module system is written
2636: within the language, using records, explicit laziness,
2637: and functors implemented by higher-order procedures.
2638:
2639: \item It is important to have a powerful interface
2640: to a lower-level language.
2641: Mozart has a C++ interface that allows to add new
2642: constraint systems~\cite{cinterface,cetutorial}.
2643: These constraint systems are fully integrated
2644: into the system, including taking advantage
2645: of the full power of computation spaces.
2646: The current Mozart system has four constraint systems,
2647: based on rational trees
2648: (for both ``bound records'' and ``free records''~\cite{VMS:PLILP96}),
2649: finite domains~\cite{fdtutorial}, and finite sets~\cite{fstutorial}.
2650: Mozart also supports memory management across
2651: the interface, with garbage collection from the Oz side
2652: (using finalization and weak pointers)
2653: and manual control from the C++ side.
2654: \end{itemize}
2655:
2656: \subsection{Support true multiparadigm programming}
2657: \label{supportmp}
2658:
2659: In any large programming project,
2660: it is almost always a good idea to
2661: use more than one paradigm:
2662: \begin{itemize}
2663: \item Different parts are often best programmed
2664: in different paradigms.\footnote{Another
2665: approach is to use multiple languages with
2666: well-defined interfaces.
2667: This is more complex, but can sometimes work well.}
2668: For example, an event handler may be defined as
2669: an active object whose new state
2670: is a function of its previous state and an external event.
2671: This uses both the object-oriented and functional paradigms
2672: and encapsulates the concurrency in the active object.
2673: \item Different levels of abstraction are often best
2674: expressed in different paradigms.
2675: For example, consider a multi-agent system programmed in
2676: a concurrent logic language.
2677: At the language level, the system does not have the concept of state.
2678: But there is a higher level, the agent level,
2679: consisting of stateful entities called ``agents'' sending
2680: messages to each other.
2681: Strictly speaking,
2682: these concepts do not exist at the language level.
2683: To reason about them, the agent level
2684: is better specified as a graph of active objects.
2685: \end{itemize}
2686: It is always possible to {\em encode} one paradigm
2687: in terms of another.
2688: Usually this is not a good idea.
2689: We explain why in one particularly interesting case,
2690: namely pure concurrent logic programs with state~\cite{portpaper}.
2691: The canonical way to encode state
2692: in a pure concurrent logic program is by using {\em streams}.
2693: An active object is a recursive predicate
2694: that reads an internal stream.
2695: The object's current state is
2696: the internal stream's most-recent element.
2697: A {\em reference} to an active object is a stream that
2698: is read by that object.
2699: This reference can only be used by one sender object,
2700: which sends messages by binding the stream's tail.
2701: Two sender objects sending messages to a third object
2702: are coded as two streams feeding a {\em stream merger},
2703: whose output stream then feeds the third object.
2704: Whenever a new reference is created,
2705: a new stream merger has to be created.
2706: The system as a whole is therefore more complex
2707: than a system with state:
2708: \begin{itemize}
2709: \item The communication graph of the active objects is encoded
2710: as a network of streams and stream mergers.
2711: In this network, each object has a tree of
2712: stream mergers feeding into it.
2713: The trees are created incrementally
2714: during execution, as object references
2715: are passed around the system.
2716: % The path between a sending and receiving object
2717: % in the network depends
2718: % not only on them, but also on how the sender
2719: % initially got a reference to a stream that is read by the receiver.
2720: % This reference may have been passed through any number
2721: % of third party objects before finally reaching the sender.
2722: % Each third party object may have created a stream merger.
2723: \item To regain efficiency,
2724: the compiler and run-time system must be smart enough to discover
2725: that this network is equivalent to a much simpler structure
2726: in which senders send directly to receivers.
2727: This ``decompilation'' algorithm is so complex
2728: that to our knowledge
2729: no concurrent logic system implements it.
2730: \end{itemize}
2731: On the other hand,
2732: adding state directly to the execution model
2733: makes the system simpler and more uniform.
2734: In that case, programmer-visible state (e.g., active objects with identities) is
2735: mapped directly to execution model state (e.g., using ports for many-to-one
2736: communication),
2737: which is compiled directly into machine state.
2738: Both the compiler and the run-time system are simple.
2739: One may argue that the stateful execution model
2740: is no longer ``pure''.
2741: This is true but irrelevant,
2742: since the stateful model allows simpler reasoning
2743: than the ``pure'' stateless one.
2744:
2745: Similar examples can be found for other concepts, e.g.,
2746: higher-orderness,
2747: concurrency,
2748: exception handling,
2749: search,
2750: and
2751: laziness~\cite{book}.
2752: In each case, encoding the concept increases the complexity
2753: of both the program and the system implementation.
2754: In each case, adding the concept to the execution model gives
2755: a simpler and more uniform system.
2756: We conclude that a programming language
2757: should support multiple paradigms.
2758:
2759: \subsection{Combine dynamic and static typing}
2760: \label{dynamictype}
2761:
2762: % Optionally protect (armor-plate) encapsulated program fragments
2763: % (procedures, modules, objects) from undesired external interference.
2764: % Should be an option, not an obligation. Wrong types could give an
2765: % exception at run-time (like in E).
2766:
2767: We define a {\em type} as a set of values
2768: along with a set of operations on those values.
2769: We say that a language has {\em checked types}
2770: if the system enforces that operations
2771: are only executed with values of correct types.
2772: There are two basic approaches to checked typing,
2773: namely dynamic and static typing.
2774: In {\em static typing}, all variable types are known at compile time.
2775: No type errors can occur at run-time.
2776: In {\em dynamic typing}, the variable type is known with
2777: certainty only when the variable is bound.
2778: If a type error occurs at run-time, then an exception is raised.
2779: Oz is a dynamically-typed language.
2780: Let us examine the trade-offs in each approach.
2781:
2782: Dynamic typing puts fewer restrictions
2783: on programs and programming than static typing.
2784: For example, it allows Oz to have an incremental
2785: development environment that is part of the run-time system.
2786: It allows to test programs or program fragments
2787: even when they are in an incomplete or inconsistent state.
2788: It allows truly open programming, i.e., independently-written
2789: components can come together and interact with
2790: as few assumptions as possible about each other.
2791: It allows programs, such as operating systems,
2792: that run indefinitely and grow and evolve.
2793:
2794: On the other hand,
2795: static typing has at least three advantages
2796: when compared to dynamic typing.
2797: It allows to catch more program errors at compile time.
2798: It allows for a more efficient implementation,
2799: since the compiler can choose a representation
2800: appropriate for the type.
2801: Last but not least,
2802: it allows for partial program verification,
2803: since some program properties can be guaranteed by the type checker.
2804:
2805: In our experience, we find that neither approach is always clearly better.
2806: Sometimes flexibility is what matters; at other times
2807: having guarantees is more important.
2808: It seems therefore that the right type system should be ``mixed'',
2809: that is, be a combination of static and dynamic typing.
2810: This allows the following development methodology,
2811: which is consistent with our experience.
2812: In the early stages of application development,
2813: when we are building prototypes,
2814: dynamic typing is used to maximize flexibility.
2815: Whenever a part of the application is completed,
2816: then it is statically typed
2817: to maximize correctness guarantees and efficiency.
2818: For example, module interfaces and procedure arguments
2819: could be statically typed to maximize early detection of errors.
2820: The most-executed part of a program could be
2821: statically typed to maximize its efficiency.
2822:
2823: Much work has been done to
2824: add some of the advantages of dynamic typing to
2825: a statically-typed language, while keeping the
2826: good properties of static typing:
2827: \begin{itemize}
2828: \item Polymorphism adds flexibility to functional and
2829: object-oriented languages.
2830: \item Type inferencing, pioneered by ML, relieves the programmer
2831: of the burden of having to type the whole program explicitly.
2832: \end{itemize}
2833: Our proposal for a mixed type system would go in the opposite direction.
2834: In the mixed type system, the default is dynamic typing.
2835: Static typing is done as soon as needed, but not before.
2836: This means that the trade-off between flexibility and having guarantees
2837: is not frozen by the language design,
2838: but is made available to the programmer.
2839: The design of this mixed type system is a subject for future research.
2840:
2841: Mixed typing is related to the concept of ``soft typing'',
2842: an approach to type checking for dynamically-typed languages~\cite{soft}.
2843: In soft typing,
2844: the type checker cannot always decide at compile time
2845: whether the program is correctly typed.
2846: When it cannot decide,
2847: it inserts run-time checks to ensure safe execution.
2848: Mixed typing differs from soft typing in that
2849: we would like to avoid the inefficiency of run-time checking,
2850: which can potentially change a program's time complexity.
2851: The statically-typed parts should be truly statically typed.
2852:
2853: % While static typing allows earlier detection of
2854: % some classes of program errors than dynamic typing,
2855: % this is offset by two factors: first, the incremental
2856: % development environment permitted by dynamic typing
2857: % and second, not having to reformulate the program
2858: % to fit within the limitations of the type system.
2859: % In our experience, the {\em really tough} errors,
2860: % i.e., the ones that take up most debugging time,
2861: % are not type errors at all,
2862: % but come from deeper misunderstandings about semantics.
2863:
2864: \subsection{Use an evolutionary development methodology}
2865: \label{methodology}
2866:
2867: The development methodology used in the Oz project
2868: has been refined over many years,
2869: and is largely responsible for the combination
2870: of expressive power, semantic simplicity,
2871: and implementation efficiency in Mozart.
2872: The methodology is nowhere fully described in print;
2873: there are only partial explanations~\cite{opm,sendai99}.
2874: We summarize it here.
2875:
2876: At all times during development, there is a robust implementation.
2877: However, the system's design is in continuous flux.
2878: The system's developers continuously introduce
2879: new abstractions as solutions to practical problems.
2880: The burden of proof is on the developer proposing the abstraction:
2881: he must prototype it and show an application
2882: for which it is necessary.
2883: The net effect of a new abstraction
2884: must be either to simplify the system
2885: or to greatly increase its expressive power.
2886: If this seems to be the case,
2887: then intense discussion takes place among all developers
2888: to simplify the abstraction as much as possible.
2889: Often it vanishes: it can be completely expressed
2890: without modifying the system.
2891: This is not always possible.
2892: Sometimes it is better to modify the system:
2893: to extend it or to replace an existing
2894: abstraction by a new one.
2895:
2896: The decision whether to accept an abstraction
2897: is made according to
2898: several criteria including aesthetic ones.
2899: Two major acceptance criteria are related to
2900: implementation and formalization.
2901: The abstraction is acceptable only if
2902: its implementation is efficient
2903: and its formalization is simple.
2904:
2905: This methodology extends the approaches put forward by
2906: Hoare, Ritchie, and Thompson~\cite{hoare,ritchie,thompson}.
2907: Hoare advocates designing a program
2908: and its specification concurrently.
2909: He also explains the importance
2910: of having a simple core language.
2911: Ritchie advises having the designers and others actually
2912: use the system during the development period.
2913: In Mozart, as in most Prolog systems, this is
2914: possible because the development environment
2915: is part of the run-time system.
2916: Thompson shows the power of a well-designed abstraction.
2917: The success of Unix was made possible due to its
2918: simple, powerful, and appropriate abstractions.
2919:
2920: With respect to traditional software design processes,
2921: this methodology is closest to {\em exploratory programming},
2922: which consists in developing an initial implementation,
2923: exposing it to user comment,
2924: and refining it until the system is adequate~\cite{sommerville}.
2925: The main defect of exploratory programming,
2926: that it results in systems with ill-defined structure,
2927: is avoided by the way the abstractions are refined and
2928: by the double requirement of efficient implementation
2929: and simple formalization.
2930:
2931: The two-step process of first generating abstractions and then
2932: selecting among them is analogous to the basic process of evolution.
2933: In evolution, an unending source of different individuals
2934: is followed by a filter, survival of the fittest~\cite{darwin}.
2935: In the analogy, the individuals are abstractions
2936: and the filters are the two acceptance criteria
2937: of efficient implementation and simple formalization.
2938: Some abstractions thrive (e.g., compositionality with lexical scoping),
2939: others die
2940: (e.g., the ``generate and test'' approach to search is dead,
2941: being replaced by propagate and distribute),
2942: others are born and mature
2943: (e.g., dynamic scope, which is currently under discussion),
2944: and others become instances of more general ones
2945: (e.g., deep guards, once basic, are now implemented with spaces).
2946:
2947: \section{Conclusions and perspectives}
2948:
2949: % When are Horn clauses a good idea?
2950: % Not for most GP programming: they are just too flat (flat between
2951: % clauses and flat within a clause).
2952: % Perhaps for tables of information, and minor extensions of
2953: % tables that need some deduction.
2954: % Perhaps for syntactic transformations that are expressible as
2955: % grammar clauses.
2956: % In these cases, it might be a good idea to provide a Horn clause
2957: % parser for Oz.
2958: % Perhaps a Horn construct inside a compositional language? Case
2959: % extensions towards this are possible.
2960:
2961: The Oz language provides powerful tools for both
2962: the algorithmic and search classes of logic programming problems.
2963: In particular, there are many tools for taming search
2964: in real-world situations.
2965: These tools include global constraints, search heuristics,
2966: and interactive libraries to visualize and guide the
2967: search process.
2968:
2969: Oz is based on a lean execution model that subsumes
2970: deterministic logic programming,
2971: concurrent logic programming,
2972: nondeterministic logic programming,
2973: constraint programming,
2974: strict and nonstrict functional programming,
2975: and concurrent object-oriented programming.
2976: Oz supports declarative concurrency,
2977: a little-known form of concurrent programming
2978: that deserves to be more widely known.
2979: Because of appropriate syntactic and implementation
2980: support, all these paradigms are easy to use.
2981: We say that Oz is {\em multiparadigm}.
2982: It is important to be multiparadigm
2983: because good program design often requires
2984: different paradigms to be used for different parts of a program.
2985: To a competent Oz programmer, the conventional boundaries
2986: between paradigms are artificial and irrelevant.
2987:
2988: The Mozart system implements Oz and is in continuing
2989: development by the Mozart Consortium~\cite{mozart110}.
2990: Research and development started in 1991.
2991: The current release has a full-featured development environment
2992: and is being used for serious application development.
2993: This article covers most of the basic language primitives of Oz.
2994: We only briefly discussed the object system,
2995: the module system (i.e., functors),
2996: and constraint programming, because of space limitations.
2997: In addition to ongoing research in constraint programming,
2998: we are doing research in
2999: distribution,
3000: fault tolerance,
3001: security,
3002: transactions,
3003: persistence,
3004: programming environments,
3005: software component architectures,
3006: tools for collaborative applications, and
3007: graphic user interfaces.
3008: Another important topic, as yet unexplored,
3009: is the design of a mixed type system
3010: that combines the advantages of static and dynamic typing.
3011: % Finally, it may be useful to add a preprocessor
3012: % for a Horn clause syntax.
3013: The work on distribution and related areas started in 1995~\cite{perdio}.
3014: Most of these areas are traditionally given short shrift by the
3015: logic and functional programming communities,
3016: yet they merit special attention due to their importance
3017: for real-world applications.
3018:
3019: \section*{Acknowledgements}
3020:
3021: This article is based on the work of many people over many years.
3022: We thank all the contributors
3023: and developers of the Mozart system.
3024: Many of the opinions expressed are shared
3025: by other members of the Mozart Consortium.
3026: We thank Danny De Schreye for suggesting
3027: the ICLP99 tutorial on which this article is based.
3028: We thank Krzysztof Apt,
3029: Manuel Hermenegildo, Kazunori Ueda,
3030: and others for their questions and comments
3031: at the ICLP99 tutorial
3032: where the original talk was given.
3033: We thank the anonymous referees for their comments
3034: that helped us much improve the presentation.
3035: Finally, we give a special thanks to Juris Reinfelds.
3036: This research was partly financed
3037: by the Walloon Region of Belgium in the PIRATES project.
3038:
3039: \bibliography{paper}
3040:
3041: \begin{thebibliography}{}
3042:
3043: \bibitem[\protect\citename{Abelson {\em et~al.}\relax, }1996]{abelson2}
3044: Abelson, Harold, Sussman, Gerald~Jay, \& Sussman, Julie. (1996).
3045: \newblock {\em Structure and interpretation of computer programs, second
3046: edition}.
3047: \newblock Cambridge, Mass: The MIT Press.
3048:
3049: \bibitem[\protect\citename{{A\"{\i}t-Kaci} \& Lincoln,
3050: }1988]{Ait-Kaci+Lincoln/88/LIFE}
3051: {A\"{\i}t-Kaci}, Hassan, \& Lincoln, Patrick. 1988 (Feb.).
3052: \newblock {\em {LIFE}: {A} natural language for natural language}.
3053: \newblock MCC Technical Report ACA-ST-074-88. MCC, ACA Program.
3054:
3055: \bibitem[\protect\citename{A{\"\i}t-Kaci \& Nasr, }1989]{life89}
3056: A{\"\i}t-Kaci, Hassan, \& Nasr, Roger. (1989).
3057: \newblock Integrating logic and functional programming.
3058: \newblock {\em Journal of lisp and symbolic computation}, {\bf 2}, 51--89.
3059:
3060: \bibitem[\protect\citename{A\"{\i}t-Kaci \& Podelski, }1993]{jlplife}
3061: A\"{\i}t-Kaci, Hassan, \& Podelski, Andreas. (1993).
3062: \newblock Towards a meaning of {LIFE}.
3063: \newblock {\em J. log. prog.}, {\bf 16}(3-4), 195--234.
3064:
3065: \bibitem[\protect\citename{A{\"\i}t-Kaci {\em et~al.}\relax,
3066: }1994]{wildlife-handbook}
3067: A{\"\i}t-Kaci, Hassan, Dumant, Bruno, Meyer, Richard, Podelski, Andreas, \&
3068: {Van Roy}, Peter. (1994).
3069: \newblock {\em The {W}ild {LIFE} handbook}.
3070: \newblock Available at \verb+http://www.info.ucl.ac.be/people/PVR/handbook.ps+.
3071:
3072: \bibitem[\protect\citename{Armstrong {\em et~al.}\relax, }1996]{erlang}
3073: Armstrong, Joe, Williams, Mike, Wikstr{\"o}m, Claes, \& Virding, Robert.
3074: (1996).
3075: \newblock {\em Concurrent programming in {Erlang}}.
3076: \newblock Englewood Cliffs, N.J.: Prentice-Hall.
3077:
3078: \bibitem[\protect\citename{Arnold \& Gosling, }1998]{javabook}
3079: Arnold, Ken, \& Gosling, James. (1998).
3080: \newblock {\em The {Java} programming language, second edition}.
3081: \newblock Addison Wesley.
3082:
3083: \bibitem[\protect\citename{Ashenhurst \& Graham, }1987]{turingaward}
3084: Ashenhurst, Robert~L., \& Graham, Susan (eds). (1987).
3085: \newblock {\em {ACM} {Turing Award} lectures: The first twenty years}.
3086: \newblock ACM Press.
3087:
3088: \bibitem[\protect\citename{Bal {\em et~al.}\relax,
3089: }1989]{BalSteinerTanenbaum:89}
3090: Bal, Henri~E., Steiner, Jennifer~G., \& Tanenbaum, Andrew~S. (1989).
3091: \newblock Programming languages for distributed computing systems.
3092: \newblock {\em Acm computing surveys}, {\bf 21}(3), 261--322.
3093:
3094: \bibitem[\protect\citename{Baumgartner {\em et~al.}\relax, }2001]{brew}
3095: Baumgartner, Gerald, Jansche, Marin, \& Peisert, Christophe~D. (2001).
3096: \newblock Support for functional programming in {Brew}.
3097: \newblock {\em Pages 111--125 of:} {\em Workshop on multiparadigm programming
3098: with object-oriented languages (mpool), european conference on
3099: object-oriented programming (ecoop)}.
3100: \newblock NIC, vol. 7.
3101: \newblock John von Neumann Institute for Computing.
3102:
3103: \bibitem[\protect\citename{Budd, }1995]{leda}
3104: Budd, Timothy~A. (1995).
3105: \newblock {\em Multiparadigm programming in {Leda}}.
3106: \newblock Addison-Wesley.
3107:
3108: \bibitem[\protect\citename{{Carlsson {\em et al}}, }1999]{sicstus}
3109: {Carlsson {\em et al}}, Mats. 1999 (Dec.).
3110: \newblock {\em {SICStus} {Prolog} 3.8.1}.
3111: \newblock Available at {\tt http://www.sics.se}.
3112:
3113: \bibitem[\protect\citename{Carriero \& Gelernter, }1989]{CarrieroGelernter:89}
3114: Carriero, Nicholas, \& Gelernter, David. (1989).
3115: \newblock Linda in context.
3116: \newblock {\em Communications of the acm}, {\bf 32}(4), 444--458.
3117:
3118: \bibitem[\protect\citename{Carriero \& Gelernter, }1992]{linda}
3119: Carriero, Nicholas, \& Gelernter, David. (1992).
3120: \newblock Coordination languages and their significance.
3121: \newblock {\em Communications of the acm}, {\bf 35}(2), 96--107.
3122:
3123: \bibitem[\protect\citename{Cartwright \& Fagan, }1991]{soft}
3124: Cartwright, Robert, \& Fagan, Mike. 1991 (June).
3125: \newblock Soft typing.
3126: \newblock {\em Pages 278--292 of:} {\em Proceedings of the acm sigplan '91
3127: conference on programming language design and implementation (pldi)}.
3128:
3129: \bibitem[\protect\citename{Caseau {\em et~al.}\relax, }1999a]{claire}
3130: Caseau, Yves, Josset, Fran\c{c}ois-Xavier, \& Laburthe, Fran\c{c}ois. (1999a).
3131: \newblock {CLAIRE}: Combining sets, search and rules to better express
3132: algorithms.
3133: \newblock {\em Pages 245--259 of:} {\em Proceedings of the 1999 international
3134: conference on logic programming (iclp 99)}.
3135: \newblock Las Cruces, NM, USA: The MIT Press.
3136:
3137: \bibitem[\protect\citename{Caseau {\em et~al.}\relax, }1999b]{caseau_meta_cp99}
3138: Caseau, Yves, Laburthe, Fran{\c{c}}ois, \& Silverstein, Glenn. 1999b (Oct.).
3139: \newblock A meta-heuristic factory for vehicle routing problems.
3140: \newblock {\em Pages 144--158 of:} Jaffar, Joxan (ed), {\em Proceedings of the
3141: fifth international conference on principles and practice of constraint
3142: programming (cp '99)}.
3143:
3144: \bibitem[\protect\citename{Chailloux {\em et~al.}\relax, }2000]{ocaml}
3145: Chailloux, Emmanuel, Manoury, Pascal, \& Pagano, Bruno. (2000).
3146: \newblock {\em D\'eveloppement d'applications avec {Objective Caml}}.
3147: \newblock Paris, France: O'Reilly.
3148: \newblock In French.
3149:
3150: \bibitem[\protect\citename{Chakravarty {\em et~al.}\relax,
3151: }1995]{ChakravartyEtAl:95}
3152: Chakravarty, M., Guo, Y., \& {K\"ohler}, M. 1995 (May).
3153: \newblock {Goffin}: Higher-order functions meet concurrent constraints.
3154: \newblock {\em First international workshop on concurrent constraint
3155: programming}.
3156: \newblock Venice, Italy.
3157:
3158: \bibitem[\protect\citename{Chen {\em et~al.}\relax, }1993]{hilog}
3159: Chen, Weidong, Kifer, Michael, \& Warren, David~S. (1993).
3160: \newblock {HiLog}: A foundation for higher-order logic programming.
3161: \newblock {\em J. log. prog.}, {\bf 15}(3), 187--230.
3162:
3163: \bibitem[\protect\citename{Clark, }1987]{lncs259*30}
3164: Clark, Keith~L. (1987).
3165: \newblock {PARLOG}: the language and its applications.
3166: \newblock {\em Pages 30--53 of:} de~Bakker, A. J. Nijman J.~W., \& Treleaven,
3167: P.~C. (eds), {\em Proceedings of the conference on parallel architectures and
3168: languages europe ({PARLE}). volume {II}: Parallel languages}.
3169: \newblock Lecture Notes in Computer Science, vol. 259.
3170: \newblock Eindhoven, The Netherlands: Springer Verlag.
3171:
3172: \bibitem[\protect\citename{Clark \& McCabe, }1979]{CM79:}
3173: Clark, Keith~L., \& McCabe, Frank. (1979).
3174: \newblock The control facilities of {IC-Prolog}.
3175: \newblock {\em Pages 122--149 of:} Michie, D. (ed), {\em Expert systems in the
3176: micro-electronic age}.
3177: \newblock Edinburgh, Scotland: Edinburgh University Press.
3178:
3179: \bibitem[\protect\citename{Clark \& T{\"a}rnlund, }1977]{difflist}
3180: Clark, Keith~L., \& T{\"a}rnlund, Sten-{\AA}ke. (1977).
3181: \newblock A first order theory of data and programs.
3182: \newblock {\em Pages 939--944 of:} {\em Proceedings of the ifip congress}.
3183: \newblock Toronto, Canada: North-Holland.
3184:
3185: \bibitem[\protect\citename{Clark {\em et~al.}\relax, }1982]{Clar82a}
3186: Clark, Keith~L., McCabe, Frank~G., \& Gregory, Steve. (1982).
3187: \newblock {IC}-{PROLOG} --- language features.
3188: \newblock {\em Pages 253--266 of:} Clark, Keith~L., \& T{\"a}rnlund,
3189: Sten-{\AA}ke (eds), {\em Logic programming}.
3190: \newblock London: Academic Press.
3191:
3192: \bibitem[\protect\citename{Clinger \& Rees, }1991]{R4RS:91}
3193: Clinger, William, \& Rees, Jonathan. (1991).
3194: \newblock The revised${}^4$ report on the algorithmic language {Scheme}.
3195: \newblock {\em Lisp pointers}, {\bf IV}(3), 1--55.
3196:
3197: \bibitem[\protect\citename{Colmerauer, }1982]{colmerauer82}
3198: Colmerauer, Alain. 1982 (Oct.).
3199: \newblock {\em {PROLOG} {II} reference manual and theoretical model}.
3200: \newblock Tech. rept. Universit\'{e} Aix-Marseille {II}, Groupe d'Intelligence
3201: Artificielle.
3202:
3203: \bibitem[\protect\citename{Cousineau \& Mauny, }1998]{caml}
3204: Cousineau, Guy, \& Mauny, Michel. (1998).
3205: \newblock {\em The functional approach to programming}.
3206: \newblock Cambridge University Press.
3207:
3208: \bibitem[\protect\citename{Darwin, }1964]{darwin}
3209: Darwin, Charles. (1964).
3210: \newblock {\em On the origin of species by means of natural selection, or the
3211: preservation of favoured races in the struggle for life}.
3212: \newblock Harvard University Press (originally John Murray, London, 1859).
3213:
3214: \bibitem[\protect\citename{Davison, }1993]{Davison:93}
3215: Davison, Andrew. (1993).
3216: \newblock A survey of logic programming-based object oriented languages.
3217: \newblock {\em Research directions in concurrent object-oriented programming}.
3218: \newblock The MIT Press.
3219:
3220: \bibitem[\protect\citename{Duchier, }1999]{duchier-mol6}
3221: Duchier, Denys. 1999 (July).
3222: \newblock Axiomatizing dependency parsing using set constraints.
3223: \newblock {\em Sixth meeting on mathematics of language (mol6)}.
3224:
3225: \bibitem[\protect\citename{Duchier {\em et~al.}\relax, }1998]{modules-98}
3226: Duchier, Denys, Kornstaedt, Leif, Schulte, Christian, \& Smolka, Gert. (1998).
3227: \newblock {\em {A Higher-order Module Discipline with Separate Compilation,
3228: Dynamic Linking, and Pickling}}.
3229: \newblock Tech. rept. Programming Systems Lab, DFKI and Universit{\"a}t des
3230: Saarlandes.
3231: \newblock DRAFT.
3232:
3233: \bibitem[\protect\citename{Duchier {\em et~al.}\relax, }1999a]{DucGarNie99}
3234: Duchier, Denys, Gardent, Claire, \& Niehren, Joachim. (1999a).
3235: \newblock {\em Concurrent constraint programming in {O}z for natural language
3236: processing}.
3237: \newblock Lecture notes, {\tt
3238: http://www.ps.uni-sb.de/Papers/abstracts/oznlp.html}.
3239:
3240: \bibitem[\protect\citename{Duchier {\em et~al.}\relax, }1999b]{systemmodules}
3241: Duchier, Denys, Kornstaedt, Leif, {M\"uller}, Tobias, Schulte, Christian, \&
3242: {Van Roy}, Peter. 1999b (Jan.).
3243: \newblock {\em System modules}.
3244: \newblock Tech. rept. Mozart Consortium.
3245: \newblock Available at {\tt http://www.mozart-oz.org}.
3246:
3247: \bibitem[\protect\citename{Foster, }1993]{Foster:PCN-Strand:93}
3248: Foster, Ian. (1993).
3249: \newblock {\em {Strand} and {PCN}: Two generations of compositional programming
3250: languages}.
3251: \newblock Tech. rept. Preprint MCS-P354-0293. Argonne National Laboratories.
3252:
3253: \bibitem[\protect\citename{Fujise {\em et~al.}\relax, }1994]{klic}
3254: Fujise, Tetsuro, Chikayama, Takashi, Rokusawa, Kazuaki, \& Nakase, Akihiko.
3255: 1994 (Dec.).
3256: \newblock {KLIC}: {A} portable implementation of {KL1}.
3257: \newblock {\em Pages 66--79 of:} {\em Fifth generation computing systems (fgcs
3258: '94)}.
3259:
3260: \bibitem[\protect\citename{Gabbay {\em et~al.}\relax,
3261: }1995]{GabbayHoggerRobinson:95}
3262: Gabbay, Dov~M., Hogger, Christopher~J., \& Robinson, John~Alan (eds). (1995).
3263: \newblock {\em Handbook of logic in artificial intelligence and logic
3264: programming}.
3265: \newblock Vol. 5.
3266: \newblock Oxford University Press.
3267:
3268: \bibitem[\protect\citename{Garey \& Johnson, }1979]{Garey.79}
3269: Garey, Michael~R., \& Johnson, David~S. (1979).
3270: \newblock {\em Computers and intractibility}.
3271: \newblock W.H. Freeman and Co.
3272:
3273: \bibitem[\protect\citename{Goldberg \& Robson, }1983]{smalltalk80}
3274: Goldberg, Adele, \& Robson, David. (1983).
3275: \newblock {\em Smalltalk-80: The language and its implementation}.
3276: \newblock Addison-Wesley.
3277:
3278: \bibitem[\protect\citename{Halstead, }1985]{halstead}
3279: Halstead, Robert~H. (1985).
3280: \newblock {MultiLisp}: A language for concurrent symbolic computation.
3281: \newblock {\em Acm transactions on programming languages and systems}, {\bf
3282: 7}(4), 501--538.
3283:
3284: \bibitem[\protect\citename{Hanus, }1994]{Hanus:JLP:94}
3285: Hanus, Michael. (1994).
3286: \newblock The integration of functions into logic programming: From theory to
3287: practice.
3288: \newblock {\em J. log. prog.}, {\bf 19/20}, 583--628.
3289:
3290: \bibitem[\protect\citename{Hanus, }1997]{curry}
3291: Hanus, Michael. 1997 (Jan.).
3292: \newblock A unified computation model for functional and logic programming.
3293: \newblock {\em Pages 80--93 of:} {\em Proceedings of the 24th acm
3294: sigplan-sigact symposium on principles of programming languages (popl 97)}.
3295:
3296: \bibitem[\protect\citename{Haridi \& Brand, }1988]{andorra}
3297: Haridi, Seif, \& Brand, Per. (1988).
3298: \newblock {Andorra} {Prolog} -- an integration of {Prolog} and committed-choice
3299: languages.
3300: \newblock {\em Pages 745--754 of:} of~New Generation Computer
3301: Technology~(ICOT), Institute (ed), {\em Proceedings of the international
3302: conference on fifth generation computer systems (fgcs)}, vol. 2.
3303: \newblock Tokyo, Japan: Ohmsha Ltd. and Springer Verlag.
3304:
3305: \bibitem[\protect\citename{Haridi \& Janson, }1990]{akl}
3306: Haridi, Seif, \& Janson, Sverker. (1990).
3307: \newblock {Kernel} {Andorra Prolog} and its computation model.
3308: \newblock {\em Pages 31--48 of:} {\em Proceedings of the 7th international
3309: conference on logic programming (iclp 90)}.
3310: \newblock Jerusalem, Israel: The MIT Press.
3311:
3312: \bibitem[\protect\citename{Haridi {\em et~al.}\relax, }1998]{ngc98}
3313: Haridi, Seif, {Van Roy}, Peter, Brand, Per, \& Schulte, Christian. (1998).
3314: \newblock Programming languages for distributed applications.
3315: \newblock {\em New generation computing}, {\bf 16}(3), 223--261.
3316:
3317: \bibitem[\protect\citename{Haridi {\em et~al.}\relax, }1999]{toplas99}
3318: Haridi, Seif, {Van Roy}, Peter, Brand, Per, Mehl, Michael, Scheidhauer, Ralf,
3319: \& Smolka, Gert. (1999).
3320: \newblock Efficient logic variables for distributed computing.
3321: \newblock {\em Acm transactions on programming languages and systems}, {\bf
3322: 21}(3), 569--626.
3323:
3324: \bibitem[\protect\citename{Harper {\em et~al.}\relax,
3325: }1986]{HarperMacQueenMilner:86}
3326: Harper, Robert, MacQueen, Dave, \& Milner, Robin. (1986).
3327: \newblock {\em {Standard ML}}.
3328: \newblock Tech. rept. ECS-LFCS-86-2. University of Edinburgh, Dept. of Computer
3329: Science.
3330:
3331: \bibitem[\protect\citename{Henz, }1997a]{HenzOFCCP:97}
3332: Henz, Martin. (1997a).
3333: \newblock {\em Objects for concurrent constraint programming}.
3334: \newblock The Kluwer International Series in Engineering and Computer Science,
3335: vol. 426.
3336: \newblock Boston: Kluwer Academic Publishers.
3337:
3338: \bibitem[\protect\citename{Henz, }1997b]{HenzDiss:97}
3339: Henz, Martin. 1997b (June).
3340: \newblock {\em Objects in {Oz}}.
3341: \newblock Ph.D. thesis, Universit\"at des Saarlandes, Fachbereich Informatik,
3342: Saarbr\"ucken, Germany.
3343:
3344: \bibitem[\protect\citename{Henz {\em et~al.}\relax, }1999]{figaro-parimplws99}
3345: Henz, Martin, M{\"u}ller, Tobias, \& Ng, Ka~Boon. 1999 (Nov.).
3346: \newblock Figaro: Yet another constraint programming library.
3347: \newblock {\em Workshop on parallelism and implementation technology for
3348: constraint logic programming, international conference on logic programming
3349: (iclp 99)}.
3350:
3351: \bibitem[\protect\citename{Hoare, }1987]{hoare}
3352: Hoare, Charles Antony~Richard. (1987).
3353: \newblock The emperor's old clothes.
3354: \newblock {\em In:} \cite{turingaward}.
3355: \newblock 1980 Turing Award Lecture.
3356:
3357: \bibitem[\protect\citename{Holmer {\em et~al.}\relax, }1996]{holmerjlp}
3358: Holmer, Bruce~K., Sano, Barton, Carlton, Michael, Roy, Peter~Van, \& Despain,
3359: Alvin~M. (1996).
3360: \newblock Design and analysis of hardware for high performance {Prolog}.
3361: \newblock {\em J. log. prog.}, {\bf 29}(Nov.), 107--139.
3362:
3363: \bibitem[\protect\citename{Hudak {\em et~al.}\relax, }1992]{haskell}
3364: Hudak, Paul, {Peyton Jones}, Simon~L., Wadler, Philip, Boutel, Brian,
3365: Fairnbairn, Jon, Fasel, Joseph~H., Guzm\'{a}n, Mar\'{\i}a~M., Hammond, Kevin,
3366: Hughes, John, Johnsson, Thomas, Kieburtz, Richard~B., Nikhil, Rishiyur~S.,
3367: Partain, Will, \& Peterson, John. (1992).
3368: \newblock Report on the programming language {Haskell}, a non-strict purely
3369: functional language.
3370: \newblock {\em Acm sigplan notices}, {\bf 27}(5), R1--R164.
3371:
3372: \bibitem[\protect\citename{Hughes, }1989]{fpmatters}
3373: Hughes, John. (1989).
3374: \newblock Why functional programming matters.
3375: \newblock {\em The computer journal}, {\bf 32}(2), 98--107.
3376:
3377: \bibitem[\protect\citename{{Institute for New Generation Computer Technology},
3378: }1992]{fgcs92}
3379: {Institute for New Generation Computer Technology} (ed). (1992).
3380: \newblock {\em Fifth generation computer systems 1992}.
3381: \newblock Vol. 1,2.
3382: \newblock Ohmsha Ltd. and IOS Press.
3383: \newblock ISBN 4-274-07724-1.
3384:
3385: \bibitem[\protect\citename{Janson, }1994]{sverkerthesis}
3386: Janson, Sverker. (1994).
3387: \newblock {\em {AKL}--a multiparadigm programming language}.
3388: \newblock Ph.D. thesis, Uppsala University and SICS.
3389:
3390: \bibitem[\protect\citename{Janson \& Haridi, }1991]{janson91}
3391: Janson, Sverker, \& Haridi, Seif. (1991).
3392: \newblock Programming paradigms of the {Andorra Kernel Language}.
3393: \newblock {\em Pages 167--183 of:} {\em Logic programming, proceedings of the
3394: 1991 international symposium (islp)}.
3395: \newblock San Diego, CA, USA: The MIT Press.
3396:
3397: \bibitem[\protect\citename{Janson {\em et~al.}\relax, }1993]{portpaper}
3398: Janson, Sverker, Montelius, Johan, \& Haridi, Seif. (1993).
3399: \newblock Ports for objects in concurrent logic programs.
3400: \newblock {\em Research directions in concurrent object-oriented programming}.
3401: \newblock The MIT Press.
3402:
3403: \bibitem[\protect\citename{K{\aa}gedal {\em et~al.}\relax, }1997]{lst97}
3404: K{\aa}gedal, Andreas, {Van Roy}, Peter, \& Dumant, Bruno. 1997 (Jan.).
3405: \newblock {\em {Logical State Threads} 0.1}.
3406: \newblock SICStus Prolog package available at {\tt
3407: http://www.info.ucl.ac.be/people/PVR/implementation.html}.
3408:
3409: \bibitem[\protect\citename{Koller \& Niehren, }2000]{CP-NL}
3410: Koller, Alexander, \& Niehren, Joachim. (2000).
3411: \newblock Constraint programming in computational linguistics.
3412: \newblock Barker-Plummer, D., Beaver, D., van Benthem, J., \& di~Luzio,
3413: P.~Scotto (eds), {\em Proceedings of the eighth csli workshop on logic
3414: language and computation}.
3415: \newblock CSLI Press.
3416:
3417: \bibitem[\protect\citename{Laburthe \& Caseau, }1998]{salsa}
3418: Laburthe, François, \& Caseau, Yves. (1998).
3419: \newblock {SALSA}: {A} language for search algorithms.
3420: \newblock {\em Pages 310--324 of:} Maher, Michael, \& Puget, Jean-François
3421: (eds), {\em Proceedings of the fourth international conference on principles
3422: and practice of constraint programming (cp '98)}.
3423: \newblock Lecture Notes in Computer Science, vol. 1520.
3424: \newblock Pisa, Italy: Springer Verlag.
3425:
3426: \bibitem[\protect\citename{Lauer \& Needham, }1978]{needhamlauer78}
3427: Lauer, Hugh~C., \& Needham, Roger~M. 1978 (Oct.).
3428: \newblock On the duality of operating system structures.
3429: \newblock {\em Second international symposium on operating systems, iria}.
3430: \newblock Reprinted in {\em Operating Systems Review}, 13(2), April 1979, pp.
3431: 3--19.
3432:
3433: \bibitem[\protect\citename{Lea, }2000]{lea2}
3434: Lea, Doug. (2000).
3435: \newblock {\em Concurrent programming in {Java}, second edition}.
3436: \newblock Addison-Wesley.
3437:
3438: \bibitem[\protect\citename{Maher, }1987]{maher87}
3439: Maher, Michael. (1987).
3440: \newblock Logic semantics for a class of committed-choice programs.
3441: \newblock {\em Pages 858--876 of:} {\em Proceedings of the fourth
3442: international conference on logic programming (iclp 87)}.
3443: \newblock Melbourne, Australia: The MIT Press.
3444:
3445: \bibitem[\protect\citename{Maier \& Warren, }1988]{maierwarren}
3446: Maier, David, \& Warren, David~S. (1988).
3447: \newblock {\em Computing with logic: Logic programming with {Prolog}}.
3448: \newblock Addison-Wesley.
3449:
3450: \bibitem[\protect\citename{Marriott \& Stuckey, }1999]{constraintprogramming}
3451: Marriott, Kim, \& Stuckey, Peter~J. (1999).
3452: \newblock {\em Programming with constraints: An introduction}.
3453: \newblock The MIT Press.
3454:
3455: \bibitem[\protect\citename{{Martin M\"{u}ller} {\em et~al.}\relax,
3456: }1995]{elephant}
3457: {Martin M\"{u}ller}, {Tobias M\"{u}ller}, \& {Van Roy}, Peter. 1995 (Dec.).
3458: \newblock Multiparadigm programming in {Oz}.
3459: \newblock Smith, Donald, Ridoux, Olivier, \& {Van Roy}, Peter (eds), {\em
3460: Workshop on the future of logic programming, international logic programming
3461: symposium (ilps 95)}.
3462:
3463: \bibitem[\protect\citename{McNamara \& Smaragdakis, }2000]{fc}
3464: McNamara, Brian, \& Smaragdakis, Yannis. 2000 (Sept.).
3465: \newblock Functional programming in {C++}.
3466: \newblock {\em Pages 118--129 of:} {\em Proceedings of the fifth acm sigplan
3467: international conference on functional programming (icfp '00)}.
3468:
3469: \bibitem[\protect\citename{Mehl, }1999]{Mehl:diss}
3470: Mehl, Michael. (1999).
3471: \newblock {\em {The Oz Virtual Machine: Records, Transients, and Deep Guards}}.
3472: \newblock Doctoral dissertation, Universität des Saarlandes, Im Stadtwald,
3473: 66041 Saarbrücken, Germany.
3474:
3475: \bibitem[\protect\citename{Mehl {\em et~al.}\relax, }1995]{amoz}
3476: Mehl, Michael, Scheidhauer, Ralf, \& Schulte, Christian. (1995).
3477: \newblock An abstract machine for {Oz}.
3478: \newblock {\em Pages 151--168 of:} Hermenegildo, Manuel, \& Swierstra,
3479: S.~Doaitse (eds), {\em Programming languages, implementations, logics and
3480: programs, seventh international symposium, plilp'95}.
3481: \newblock Lecture Notes in Computer Science, vol. 982.
3482: \newblock Utrecht, The Netherlands: Springer Verlag.
3483:
3484: \bibitem[\protect\citename{Mehl {\em et~al.}\relax, }1998]{futures}
3485: Mehl, Michael, Schulte, Christian, \& Smolka, Gert. 1998 (May).
3486: \newblock {\em Futures and by-need synchronization for {Oz}}.
3487: \newblock Draft. Programming Systems Lab, Universität des Saarlandes.
3488:
3489: \bibitem[\protect\citename{Mehl {\em et~al.}\relax, }2000]{cinterface}
3490: Mehl, Michael, {M\"uller}, Tobias, Schulte, Christian, \& Scheidhauer, Ralf.
3491: 2000 (Jan.).
3492: \newblock {\em Interfacing to {C and C++}}.
3493: \newblock Tech. rept. Mozart Consortium.
3494: \newblock Available at {\tt http://www.mozart-oz.org}.
3495:
3496: \bibitem[\protect\citename{Milner {\em et~al.}\relax,
3497: }1990]{MilnerTofteHarper:90}
3498: Milner, Robin, Tofte, Mads, \& Harper, Robert. (1990).
3499: \newblock {\em Definition of {Standard} {ML}}.
3500: \newblock Cambridge, MA, USA: The MIT Press.
3501:
3502: \bibitem[\protect\citename{Moss, }1994]{moss}
3503: Moss, Chris. (1994).
3504: \newblock {\em Prolog++: The power of object-oriented and logic programming}.
3505: \newblock Addison-Wesley.
3506:
3507: \bibitem[\protect\citename{{Mozart Consortium}, }2000]{mozart110}
3508: {Mozart Consortium}. 2000 (Jan.).
3509: \newblock {\em The {Mozart} programming system ({Oz} 3), version 1.1.0}.
3510: \newblock Available at {\tt http://www.mozart-oz.org}.
3511:
3512: \bibitem[\protect\citename{{M\"uller}, }1999]{fstutorial}
3513: {M\"uller}, Tobias. 1999 (Jan.).
3514: \newblock {\em Problem solving with finite set constraints in {Oz}. {A}
3515: tutorial.}
3516: \newblock Tech. rept. Mozart Consortium.
3517: \newblock Available at {\tt http://www.mozart-oz.org}.
3518:
3519: \bibitem[\protect\citename{{M\"uller}, }2000]{cetutorial}
3520: {M\"uller}, Tobias. 2000 (Jan.).
3521: \newblock {\em The {Mozart} constraint extensions tutorial}.
3522: \newblock Tech. rept. Mozart Consortium.
3523: \newblock Available at {\tt http://www.mozart-oz.org}.
3524:
3525: \bibitem[\protect\citename{Nadathur \& Miller, }1995]{NadathurMiller:95}
3526: Nadathur, Gopalan, \& Miller, Dale. (1995).
3527: \newblock {\em Higher-order logic programming}.
3528: \newblock Vol.~5 of \cite{GabbayHoggerRobinson:95}.
3529: \newblock Chap.~8.
3530:
3531: \bibitem[\protect\citename{Nikhil, }1994a]{Nikhil:Id:91}
3532: Nikhil, Rishiyur~S. 1994a (July).
3533: \newblock {\em {ID} language reference manual version 90.1}.
3534: \newblock Tech. rept. Memo 284-2. MIT, Computation Structures Group.
3535:
3536: \bibitem[\protect\citename{Nikhil, }1994b]{Nikhil:pH:94}
3537: Nikhil, Rishiyur~S. (1994b).
3538: \newblock {\em An overview of the parallel language {Id} -- a foundation for
3539: {pH}, a parallel dialect of {Haskell}}.
3540: \newblock Tech. rept. Digital Equipment Corporation, Cambridge Research
3541: Laboratory.
3542:
3543: \bibitem[\protect\citename{Nikhil \& Arvind, }2001]{ph}
3544: Nikhil, Rishiyur~S., \& Arvind. (2001).
3545: \newblock {\em Implicit parallel programming in {pH}}.
3546: \newblock Morgan Kaufmann.
3547:
3548: \bibitem[\protect\citename{Odersky \& Wadler, }1997]{pizza}
3549: Odersky, Martin, \& Wadler, Philip. 1997 (Jan.).
3550: \newblock Pizza into {Java}: translating theory into practice.
3551: \newblock {\em Pages 146--159 of:} {\em Proceedings of the 24th acm
3552: sigplan-sigact symposium on principles of programming languages (popl 97)}.
3553:
3554: \bibitem[\protect\citename{{Peyton Jones} \& Wadler,
3555: }1993]{PeytonJonesWadler:93}
3556: {Peyton Jones}, Simon~L., \& Wadler, Philip. 1993 (Jan.).
3557: \newblock Imperative functional programming.
3558: \newblock {\em Pages 71--84 of:} {\em Proceedings of the 20th acm
3559: sigplan-sigact symposium on principles of programming languages (popl)}.
3560:
3561: \bibitem[\protect\citename{R\'emy \& Vouillon, }1998]{ocaml2}
3562: R\'emy, Didier, \& Vouillon, J\'er\^ome. (1998).
3563: \newblock {Objective ML}: An effective object-oriented extension to {ML}.
3564: \newblock {\em Theory and practive of object systems}, {\bf 4}(1), 27--50.
3565:
3566: \bibitem[\protect\citename{Ritchie, }1987]{ritchie}
3567: Ritchie, Dennis~M. (1987).
3568: \newblock Reflections on software research.
3569: \newblock {\em In:} \cite{turingaward}.
3570: \newblock 1983 Turing Award Lecture.
3571:
3572: \bibitem[\protect\citename{Robinson, }1965]{robinson}
3573: Robinson, J.~A. (1965).
3574: \newblock A machine-oriented logic based on the resolution principle.
3575: \newblock {\em J. acm}, {\bf 12}, 23--41.
3576:
3577: \bibitem[\protect\citename{{Santos Costa} {\em et~al.}\relax,
3578: }1991]{andorramodel}
3579: {Santos Costa}, Vitor, Warren, David~H.~D., \& Yang, Rong. 1991 (Aug.).
3580: \newblock {Andorra-I}: A parallel {P}rolog system that transparently exploits
3581: both {And-} and {Or-parallelism}.
3582: \newblock {\em Pages 83--93 of:} {\em Proceedings of the 3rd acm sigplan
3583: symposium on principles and practice of parallel programming (ppopp)}.
3584:
3585: \bibitem[\protect\citename{Saraswat \& Rinard, }1990]{saraswat90}
3586: Saraswat, Vijay, \& Rinard, Martin. 1990 (Jan.).
3587: \newblock Concurrent constraint programming.
3588: \newblock {\em Pages 232--245 of:} {\em Proceedings of the 17th acm symposium
3589: on principles of programming languages (popl 90)}.
3590:
3591: \bibitem[\protect\citename{Saraswat, }1993]{SaraswatBook}
3592: Saraswat, Vijay~A. (1993).
3593: \newblock {\em Concurrent constraint programming}.
3594: \newblock The MIT Press.
3595:
3596: \bibitem[\protect\citename{Scheidhauer, }1998]{ScheidhauerDiss}
3597: Scheidhauer, Ralf. 1998 (Dec.).
3598: \newblock {\em {Design}, {Implementierung} und {Evaluierung} einer virtuellen
3599: {Maschine} {für} {Oz}}.
3600: \newblock Doctoral dissertation, Universität des Saarlandes, Im Stadtwald,
3601: 66041 Saarbrücken, Germany.
3602: \newblock In German.
3603:
3604: \bibitem[\protect\citename{Schlichting \& Thomas, }1991]{ftsrparadigm}
3605: Schlichting, Richard~D., \& Thomas, Vicraj~T. 1991 (Oct.).
3606: \newblock {\em A multi-paradigm programming language for constructing
3607: fault-tolerant, distributed systems}.
3608: \newblock Tech. rept. TR 91-24. University of Arizona, Department of Computer
3609: Science.
3610:
3611: \bibitem[\protect\citename{Schulte, }1997a]{Schulte:97}
3612: Schulte, Christian. (1997a).
3613: \newblock {Oz Explorer}: A visual constraint programming tool.
3614: \newblock {\em Pages 286--300 of:} Naish, Lee (ed), {\em Proceedings of the
3615: fourteenth international conference on logic programming (iclp 97)}.
3616: \newblock Leuven, Belgium: The MIT Press.
3617:
3618: \bibitem[\protect\citename{Schulte, }1997b]{Engines:97}
3619: Schulte, Christian. (1997b).
3620: \newblock Programming constraint inference engines.
3621: \newblock {\em Pages 519--533 of:} Smolka, Gert (ed), {\em Proceedings of the
3622: 3rd international conference on principles and practice of constraint
3623: programming}.
3624: \newblock Lecture Notes in Computer Science, vol. 1330.
3625: \newblock Schlo\ss{} Hagenberg, Austria: Springer Verlag.
3626:
3627: \bibitem[\protect\citename{Schulte, }1999a]{Schulte:ICLP99}
3628: Schulte, Christian. (1999a).
3629: \newblock Comparing trailing and copying for constraint programming.
3630: \newblock {\em Pages 275--289 of:} {De Schreye}, Danny (ed), {\em Proceedings
3631: of the 1999 international conference on logic programming (iclp 99)}.
3632: \newblock Las Cruces, NM, USA: The MIT Press.
3633:
3634: \bibitem[\protect\citename{Schulte, }1999b]{explorer}
3635: Schulte, Christian. 1999b (Jan.).
3636: \newblock {\em {Oz Explorer}--{Visual} constraint programming support}.
3637: \newblock Tech. rept. Mozart Consortium.
3638: \newblock Available at {\tt http://www.mozart-oz.org}.
3639:
3640: \bibitem[\protect\citename{Schulte, }2000a]{Schulte:00b}
3641: Schulte, Christian. 2000a (Sept.).
3642: \newblock Parallel search made simple.
3643: \newblock {\em Pages 41--57 of:} Beldiceanu, Nicolas, Harvey, Warwick, Henz,
3644: Martin, Laburthe, François, Monfroy, Eric, Müller, Tobias, Perron, Laurent,
3645: \& Schulte, Christian (eds), {\em Proceedings of {TRICS}: {T}echniques fo{R}
3646: {I}mplementing {C}onstraint programming {S}ystems, a post-conference workshop
3647: of {CP 2000}}.
3648:
3649: \bibitem[\protect\citename{Schulte, }2000b]{SchulteDiss:00}
3650: Schulte, Christian. (2000b).
3651: \newblock {\em Programming constraint inference services}.
3652: \newblock Doctoral dissertation, Universit\"at des Saarlandes, Fachbereich
3653: Informatik, Saarbr\"ucken, Germany.
3654:
3655: \bibitem[\protect\citename{Schulte, }2000c]{Schulte:00}
3656: Schulte, Christian. (2000c).
3657: \newblock Programming deep concurrent constraint combinators.
3658: \newblock {\em Pages 215--229 of:} Pontelli, Enrico, \& Costa, Vítor~Santos
3659: (eds), {\em Practical aspects of declarative languages, second international
3660: workshop, padl 2000}.
3661: \newblock Lecture Notes in Computer Science, vol. 1753.
3662: \newblock Boston, MA, USA: Springer Verlag.
3663:
3664: \bibitem[\protect\citename{Schulte, }2002]{Schulte:02}
3665: Schulte, Christian. (2002).
3666: \newblock {\em Programming constraint services}.
3667: \newblock Lecture Notes in Artificial Intelligence, vol. 2302.
3668: \newblock Berlin, Germany: Springer Verlag.
3669:
3670: \bibitem[\protect\citename{Schulte \& Smolka, }1994]{SchulteSmolka:94}
3671: Schulte, Christian, \& Smolka, Gert. (1994).
3672: \newblock Encapsulated search in higher-order concurrent constraint
3673: programming.
3674: \newblock {\em Pages 505--520 of:} Bruynooghe, Maurice (ed), {\em Logic
3675: programming: Proceedings of the 1994 international symposium}.
3676: \newblock Ithaca, NY, USA: The MIT Press.
3677:
3678: \bibitem[\protect\citename{Schulte \& Smolka, }1999]{fdtutorial}
3679: Schulte, Christian, \& Smolka, Gert. 1999 (Jan.).
3680: \newblock {\em Finite domain constraint programming in {Oz}. {A} tutorial.}
3681: \newblock Tech. rept. Mozart Consortium.
3682: \newblock Available at {\tt http://www.mozart-oz.org}.
3683:
3684: \bibitem[\protect\citename{Schulte {\em et~al.}\relax,
3685: }1994]{SchulteSmolkaEa:94}
3686: Schulte, Christian, Smolka, Gert, \& Würtz, Jörg. (1994).
3687: \newblock Encapsulated search and constraint programming in {O}z.
3688: \newblock {\em Pages 134--150 of:} Borning, Alan~H. (ed), {\em Second workshop
3689: on principles and practice of constraint programming}.
3690: \newblock Lecture Notes in Computer Science, vol. 874.
3691: \newblock Orcas Island, WA, USA: Springer Verlag.
3692:
3693: \bibitem[\protect\citename{Shapiro, }1983]{tr003}
3694: Shapiro, Ehud. 1983 (Jan.).
3695: \newblock {\em A subset of {Concurrent Prolog} and its interpreter}.
3696: \newblock Tech. rept. TR-003. Institute for New Generation Computer Technology
3697: (ICOT), Cambridge, Mass.
3698:
3699: \bibitem[\protect\citename{Shapiro, }1987]{concprolog}
3700: Shapiro, Ehud (ed). (1987).
3701: \newblock {\em Concurrent {Prolog}: Collected papers}.
3702: \newblock Vol. 1-2.
3703: \newblock Cambridge, Mass.: The MIT Press.
3704:
3705: \bibitem[\protect\citename{Shapiro, }1989]{Shapiro:89}
3706: Shapiro, Ehud. (1989).
3707: \newblock The family of concurrent logic programming languages.
3708: \newblock {\em Acm computing surveys}, {\bf 21}(3), 413--510.
3709:
3710: \bibitem[\protect\citename{Smolka, }1995a]{kerneloz}
3711: Smolka, Gert. (1995a).
3712: \newblock The definition of {K}ernel {Oz}.
3713: \newblock {\em Pages 251--292 of:} {\em Constraints: Basics and trends}.
3714: \newblock Lecture Notes in Computer Science, vol. 910.
3715: \newblock Springer Verlag.
3716:
3717: \bibitem[\protect\citename{Smolka, }1995b]{opm}
3718: Smolka, Gert. (1995b).
3719: \newblock The {Oz} programming model.
3720: \newblock {\em Pages 324--343 of:} {\em Computer science today}.
3721: \newblock Lecture Notes in Computer Science, vol. 1000.
3722: \newblock Springer Verlag.
3723:
3724: \bibitem[\protect\citename{Smolka, }1996]{constraints96}
3725: Smolka, Gert. (1996).
3726: \newblock Problem solving with constraints and programming.
3727: \newblock {\em Acm computing surveys}, {\bf 28}(4es).
3728: \newblock Electronic Section.
3729:
3730: \bibitem[\protect\citename{Smolka \& Treinen, }1994]{SmolkaTreinen:94b}
3731: Smolka, Gert, \& Treinen, Ralf. (1994).
3732: \newblock Records for logic programming.
3733: \newblock {\em J. log. prog.}, {\bf 18}(3), 229--258.
3734:
3735: \bibitem[\protect\citename{Smolka {\em et~al.}\relax, }1995]{perdio}
3736: Smolka, Gert, Schulte, Christian, \& {Van Roy}, Peter. 1995 (Feb.).
3737: \newblock {\em {PERDIO}---{Persistent} and distributed programming in {Oz}}.
3738: \newblock BMBF project proposal. Available at {\tt http://www.ps.uni-sb.de}.
3739:
3740: \bibitem[\protect\citename{Sommerville, }1992]{sommerville}
3741: Sommerville, Ian. (1992).
3742: \newblock {\em Software engineering}.
3743: \newblock Addison-Wesley.
3744:
3745: \bibitem[\protect\citename{{Steele, Jr.}, }1984]{commonlisp}
3746: {Steele, Jr.}, Guy~L. (1984).
3747: \newblock {\em Common {LISP}: The language}.
3748: \newblock Digital Press.
3749:
3750: \bibitem[\protect\citename{Sterling \& Shapiro, }1986]{artofprolog}
3751: Sterling, Leon, \& Shapiro, Ehud. (1986).
3752: \newblock {\em The art of {Prolog}--advanced programming techniques}.
3753: \newblock Series in Logic Programming.
3754: \newblock The MIT Press.
3755:
3756: \bibitem[\protect\citename{Thompson, }1987]{thompson}
3757: Thompson, Ken. (1987).
3758: \newblock Reflections on trusting trust.
3759: \newblock {\em In:} \cite{turingaward}.
3760: \newblock 1983 Turing Award Lecture.
3761:
3762: \bibitem[\protect\citename{Thompson, }1999]{haskellbook}
3763: Thompson, Simon. (1999).
3764: \newblock {\em Haskell: The craft of functional programming, second edition}.
3765: \newblock Addison-Wesley.
3766:
3767: \bibitem[\protect\citename{Tick, }1995]{deevolution}
3768: Tick, Evan. (1995).
3769: \newblock The deevolution of concurrent logic programming.
3770: \newblock {\em J. log. prog.}, {\bf 23}(2), 89--123.
3771:
3772: \bibitem[\protect\citename{Ueda, }1985]{lncs221*168}
3773: Ueda, Kazunori. (1985).
3774: \newblock {Guarded Horn Clauses}.
3775: \newblock {\em Pages 168--179 of:} Wada, Eiti (ed), {\em Logic programming
3776: '85, proceedings of the 4th conference}.
3777: \newblock Lecture Notes in Computer Science, vol. 221.
3778: \newblock Tokyo, Japan: Springer Verlag.
3779:
3780: \bibitem[\protect\citename{{Van Hentenryck}, }1999]{opl}
3781: {Van Hentenryck}, Pascal. (1999).
3782: \newblock {\em The {OPL} programming language}.
3783: \newblock The MIT Press.
3784: \newblock Software available from ILOG France.
3785:
3786: \bibitem[\protect\citename{{Van Roy}, }1989a]{edcg}
3787: {Van Roy}, Peter. (1989a).
3788: \newblock A useful extension to {Prolog}'s {Definite Clause Grammar} notation.
3789: \newblock {\em Acm sigplan notices}, {\bf 24}(11), 132--134.
3790:
3791: \bibitem[\protect\citename{{Van Roy}, }1989b]{agdi}
3792: {Van Roy}, Peter. (1989b).
3793: \newblock {\em {VLSI-BAM Diagnostic Generator}}.
3794: \newblock Prolog program to generate assembly language diagnostics, Aquarius
3795: Project, UC Berkeley, Alvin Despain.
3796:
3797: \bibitem[\protect\citename{{Van Roy}, }1999a]{mildversion}
3798: {Van Roy}, Peter. (1999a).
3799: \newblock Logic programming in {Oz} with {Mozart}.
3800: \newblock {\em Pages 38--51 of:} {De Schreye}, Danny (ed), {\em Proceedings of
3801: the 1999 international conference on logic programming (iclp 99)}.
3802: \newblock Las Cruces, NM, USA: The MIT Press.
3803: \newblock Mild version.
3804:
3805: \bibitem[\protect\citename{{Van Roy}, }1999b]{sendai99}
3806: {Van Roy}, Peter. 1999b (July).
3807: \newblock On the separation of concerns in distributed programming:
3808: {Application} to distribution structure and fault tolerance in {Mozart}.
3809: \newblock {\em International workshop on parallel and distributed computing
3810: for symbolic and irregular applications (pdsia 99)}.
3811:
3812: \bibitem[\protect\citename{{Van Roy} \& Despain, }1992]{aquarius}
3813: {Van Roy}, Peter, \& Despain, Alvin. (1992).
3814: \newblock High-performance logic programming with the {Aquarius Prolog}
3815: compiler.
3816: \newblock {\em Ieee computer}, Jan., 54--68.
3817:
3818: \bibitem[\protect\citename{{Van Roy} \& Haridi, }2002]{book}
3819: {Van Roy}, Peter, \& Haridi, Seif. (2002).
3820: \newblock {\em Concepts, techniques, and models of computer programming}.
3821: \newblock Book in progress. Draft available at
3822: \verb+http://www.info.ucl.ac.be/people/PVR/book.html+.
3823:
3824: \bibitem[\protect\citename{{Van Roy} {\em et~al.}\relax, }1996]{VMS:PLILP96}
3825: {Van Roy}, Peter, Mehl, Michael, \& Scheidhauer, Ralf. (1996).
3826: \newblock Integrating efficient records into concurrent constraint programming.
3827: \newblock {\em Proceedings of the eighth international symposium on
3828: programming languages, implementations, logics, and programs (plilp '96)}.
3829: \newblock Aachen, Germany: Springer Verlag.
3830:
3831: \bibitem[\protect\citename{{Van Roy} {\em et~al.}\relax, }1999]{dstutorial}
3832: {Van Roy}, Peter, Haridi, Seif, \& Brand, Per. 1999 (Jan.).
3833: \newblock {\em Distributed programming in {Mozart} -- {A} tutorial
3834: introduction}.
3835: \newblock Tech. rept. Mozart Consortium.
3836: \newblock Available at {\tt http://www.mozart-oz.org}.
3837:
3838: \bibitem[\protect\citename{Wadler, }1992]{Wadler:92c}
3839: Wadler, Philip. 1992 (Jan.).
3840: \newblock The essence of functional programming.
3841: \newblock {\em Pages 1--14 of:} {\em Proceedings of the 19th acm
3842: sigplan-sigact symposium on principles of programming languages (popl 92)}.
3843: \newblock Invited talk.
3844:
3845: \bibitem[\protect\citename{Wikstr{\"o}m, }1994]{derlang}
3846: Wikstr{\"o}m, Claes. (1994).
3847: \newblock Distributed programming in {Erlang}.
3848: \newblock {\em Pages 412--421 of:} {\em 1st international symposium on
3849: parallel symbolic computation (pasco 94)}.
3850: \newblock Singapore: World Scientific.
3851:
3852: \end{thebibliography}
3853: % remove for final copy
3854: % \newpage
3855: % \tableofcontents
3856:
3857: \end{document}
3858: