Title: CTM06
1CTM06
- Lecture 1Course Rationale
2Goals Contents
- The goal is to improve your ability to learn and
use state-of-the-art high-level programming
languages. - It is accomplished by studying some computation
models, some high-level linguistic abstractions
useful for programming within these models, and
some of the design patterns they enable. - All common paradigms covered, with special
attention given to different kinds of concurrency
and techniques for combining several paradigms in
the same program.
3The Three Layers
Design Patterns
Computation Model
Linguistic Abstractions
4Meta Issues for each Layer
- Why do programmers have to care about the layer?
- How is the layer best described/understood?
- What should the layer contain? When should it be
extended?
5Computation Models
- Programmers spend a lot of time doing static
analyses. This requires understanding the
underlying computation model. - Commonly described by a formal specification of
the syntax and semantics for a - calculus,
- VM assembly language, or a
- kernel language.
- Computation models should almost never be
extended. They are supposed to be minimal wrt
some problem domain.
6Linguistic Abstractions
- Linguistic abstractions are provided by libraries
and languages. Programming without them is
hardly ever worth the effort. - Common approaches to describe them
- Informal description Examples.
- Grammar Rules for translation to kernel
language. - Ideally, new linguistic abstractions are
introduced whenever the result is significantly
decreased source code complexity. However, the
value of an abstraction also depends on - the effort needed to extend the
languages/libraries involved and, - run-time overheads introduced by using the new
language/library constructs.
7Design Patterns
- By adhering to certain patterns in the way the
available linguistic abstractions are used, the
quality of the code (e.g. the maintainability)
can be improved. - There is no commonly accepted formalism for
describing design patterns. - Design patterns should be introduced whenever
this improves code quality. Much easier to add
than linguistic abstractions.
8Models Studied
- A declarative base model.
- A model providing declarative concurrency.
- A constraint model.
- A model providing explicit state.
- A model providing message-passing concurrency.
- A model providing shared-state concurrency.
- A distribution model.
9Seminar Structure
- Lectures.
- Exercise sessions.
- Home exam discussions.
- Guest lectures.
10(No Transcript)
11CTM06
- Lecture 2Basic Declarative Model
12Model Export Declaration
- All models presented in the course are extensions
of the model presented in this lecture. - In other words, it is a base model from which all
other models inherits everything.
13Outline
- Syntax semantics for a kernel language.
- Syntax semantics for some linguistic
abstractions. - Some design patterns.
- Some important properties of the kernel language.
14Kernel Statement Syntax
- skip local in end
if then else endcase of
then else end 1
nraise end !! NewName ?Name - A-ZA-Za-z_0-9character except
-
15Kernel Value Syntax
16Kernel Record Syntax
17Kernel Literal Syntax
- true false
- a-za-zA-Z0-9_'except ''
-
18Record Examples
- yes'if''red dog'
- tree(leftX rightY 2red 1color)tree(color
red rightY leftX)tree(color leftX red
rightY) - ''(a ''(b ''(c nil)))abcnila c b
- 97 100 97 a d a"ada"
19Procedure Example (1)
- Max proc X Y Z local B in
Value.' if B then Z Y else Z X end
end end - Max proc X Y Z if
Value.' end - Max proc X Y Z if X then Z Y else Z X end end
20Procedure Example (2)
- proc Max X Y Z if X X end end
- proc Max X Y Z Z if X endend
- proc Max X Y if X endend
- fun Max X Y if X
21Procedure Call Example
- Max X Y Z
- X Max Y Z
- Y Max X Z
- Z Max X Y
- Z Max X Y
22Expression Syntax
- local in
end if then else endcase
of then else end 1
n 1 n-1
raise end
23Kernel Language Semantics
- Defined by a transition relation between the
states of an abstract machine being an
interpreter of the kernel language. - A machine state consists of a constraint store
and a stack of semantic statements. - A semantic statement consists of a kernel
language statement and an environment.
24Environments
- Environments maps identifiers (variable names) to
variables and values. - Variable names may be mapped to unbound
variables. - Otherwise, there is nothing unusual in the way
environments are used. It works like in any
lexically scoped programming language with
closures.
25Constraint Stores
- A store is a logical conjunction of equality
constraints, each of which constrains a variable
to be equal to a value or to another variable. - State transitions treat constraint stores
monotonously. Information is added and garbage
collected, but never changed or removed in any
other way. This is exactly what makes the kernel
language declarative. - Whenever the information needed to continue
execution is unavailable, the current thread is
suspended until the information has arrived.
26Execution
- To execute a statement, put it on the stack with
an empty environment and an empty store and start
the machine. - Each transition begins by popping a semantic
statement from the stack. What happens next
depends on the statement. - Execution is done when a transition ends with an
empty stack or a raise-statement is popped from
the stack. - Environment fragments and variables no longer
reachable from any semantic statement on the
stack may be garbage-collected at any time.
27Execution Example (1)
Y
1
- local X in local Y in X Y Y 0end
end
local X in local Y in X Y Y 0end
end
28Execution Example (2)
2
X
Y
1
local X in local Y in X Y Y
0end end
29Execution Example (3)
3
Y
2
X
Y
1
local X in local Y in X Y Y 0end
end
30Execution Example (4)
3
Y
2
X
Y
1
Y 0
local X in local Y in X Y Y 0end
end
31Execution Example (5)
3
Y
2
X
Y
1
local X in local Y in X Y Y 0end
end
32Execution Example (6)
3
Y
X
Y
1
local X in local Y in X Y Y 0end
end
33Execution Example (7)
3
Y
0
X
Y
1
local X in local Y in X Y Y 0
end end
34Execution Example (8)
Y
0
X
Y
1
local X in local Y in X Y Y 0
end end
35Execution Example (9)
Y
1
local X in local Y in X Y Y 0 end
end
36Suspension
- proc CondBind X Y Z if X Y then Z X
endend - CondBind A A CCondBind A C 1CondBind A B
2
37Failure
- proc CondBind X Y Z if X Y then Z
X endend - CondBind A A CCondBind A C 1A 2
38Closure Example
- fun MakeInc X fun Y X Y
endend - Inc MakeInc 3Browse Inc 4Browse Inc
1
39Local-Statements (1)
local X in local Y in local Z in
... end endend
local X Y Z in ...end
40Local-Statements (2)
- local Max X Z Q in fun Max X Y if
X triple(Q, Z, W) Z X Q Max 3 6
Browse Xend
local fun Max X Y if X else X end end X triple(Q Z W) Z
X Q Max 3 6in Browse X end
41Nested Local-Statements
- local F G in local Aux in fun Aux
X ... end fun F X ... end fun
G X ... end end ... F 9 ... G 3
...end
local local fun Aux X ... end
in fun F X ... end fun G X
... end endin ... F 9 ... G 3 ...end
42Implicit Local-Statements
fun Add Vector1 Vector2 local
vector(X1 Y1 Z1) Vector1 vector(X2 Y2
Z2) Vector2 in vector(X1 X2 Y1
Y2 Z1 Z2) endend fun Add Vector1
Vector2 vector(X1 Y1 Z1) Vector1
vector(X2 Y2 Z2) Vector2in vector(X1 X2
Y1 Y2 Z1 Z2)end fun Add vector(X1 Y1
Z1) vector(X2 Y2 Z2) vector(X1 X2 Y1
Y2 Z1 Z2)end
43Case-Statements
- fun Map Xs Fun case Xs of nil then
nil else case Xs of XXs
then Fun X Map Xs Fun
else raise noSuchCase end
end endend
fun Map Xs Fun case Xs of nil then
nil XXs then Fun X Map
Xs Fun endend
44Wildcards
- fun IsTree X case X of tree(...) then
true else false endend - fun IsLeaf X case X of tree(lefttree
righttree ...) then true else
false endend
45Side Conditions
fun Filter Xs Pred case Xs of nil
then nil XYs then if
Pred X then X Filter Ys Pred
else case Xs of XYs
then Filter Ys Pred
end end endend
fun Filter Xs Pred case Xs of nil
then nil XXs andthen Pred X
X Filter Xs Pred _Xs then
Filter Xs Pred endend
46Inhibited Implicit Declarations
fun After X Xs case Xs of nil then
nil ZXs andthen Z X then
Xs ZXs then After X Xs
endend
fun After X Xs case Xs of nil then
nil !XXs then Xs _Xs
then After X Xs endend
47The Accumulator Pattern
- fun Sum Ns fun Self Ns Res case
Ns of NNs then Self
Ns Res N nil then
Res end end endin
Self Ns 0end
fun Sum Ns case Ns of nil then
0 NNs then N Sum Ns
endend
48Surprisingly Iterative
- proc Map Xs Fun ?Res case Xs of nil
then Res nil XXs then Tail in
Res Fun X Tail Map Xs Fun
Tail endend
fun Map Xs Fun case Xs of nil then
nil XXs then Fun X Map
Xs Fun endend
49Model Properties
- Fully supports the functional paradigm. In
addition, provides integrated unification and
partial values. - Imperative in the sense that there is a simple
and predictable order of execution. - Declarative in the sense that all statements can
be read as first-order predicate logic formulas.
More details presented in next lecture.
50(No Transcript)
51CTM06
- Lecture 3Declarative Concurrency
52Model Import Declaration
- Only the extensions of the base model are
presented. - Despite being far more expressive, the extended
model retains all important properties of the
base model.
53Kernel Syntax Extensions
- thread endByNeed Action ?Variable
54Thread Semantics
- Machine states may contain any number of stacks,
one for each thread, but all threads share the
same constraint store. - Threads can be suspended or active. A thread gets
suspended when the information needed for its
continued execution is not yet in the constraint
store. It gets active again by being notified by
another thread. - The precise conditions for suspension and
notification are specified for each kind of
kernel language statement. All the programmer has
to know is that threads do not waste time if no
progress can be made.
55Thread Execution
- The machine starts with one stack. Whenever a
semantic statement of the form (thread end,
Env) is popped from the stack, a new stack with
(S, Env) as its only element is added. - In each machine transition, a stack for an active
thread is selected, after which a computation
step is performed as in the base model (plus
notification). - Stack selection is fair but otherwise
unspecified. - Stacks for threads without hope of becoming
active may be garbage-collected at any time. - Execution suspends when only suspended threads
remain.
56Termination
- A thread terminates normally when its stack gets
empty. - Threads are terminated abruptly by
raise-statements, external errors and attempts to
create an inconsistent store. - Stacks for terminated threads may be
garbage-collected at any time. - Execution terminates when all threads have
terminated. It is considered a normal termination
if all threads terminated normally.
57Thread Overhead
- Threads requires little synchronization overhead
and have very small memory footprints. - A million threads should not be a problem on a
standard PC!
58Threaded Expressions (1)
59Threaded Expressions (2)
- thread if X then 0 else 1 endend
- local Res in thread if X then Res
0 else Res 1 end end Res end
60Example
fun Map Xs Fun case Xs of nil then
nil XXs then thread Fun X
end Map Xs Fun endend
61Trigger Semantics
- In every machine state, there is also a single
trigger store shared by all threads. - A trigger store is a set of triggers (P, X) such
that X is a variable and P a one-argument
procedure. - ByNeed P X adds the trigger (P, X) to the
trigger store. - Whenever a thread suspends on a variable X and
there is a trigger (P, X) in the trigger store,
the trigger is removed and the call P X is
executed in its own thread. - A trigger (P, X) is garbage-collected when X is
garbage-collected.
62Lazy Functions
- fun lazy Fun ... end
- fun Fun ... ByNeed fun endend
63Stream Example
- fun lazy IntegersFrom N N IntegersFrom
N 1end - fun lazy Map Xs Fun ... end
- Ns IntegersFrom 0Squares Map Ns Square
- Browse SquaresDelay 3000Browse Member
144 Squares
64Model Properties
- Fully supports the concurrent functional
paradigm. In addition, provides integrated
unification, partial values and dataflow
variables (both supply-driven and demand-driven). - Imperative in the sense that there is a simple
and predictable order of execution for each
thread. - Declarative in the sense that all statements can
be read as first-order predicate logic formulas.
Consequences follow.
65The Logical View of a Store
3
0
2
1
- ?1?2?3 2 3 ? 3 0
- ?x?y?z y z ? z 0
- ?y?z y z ? z 0
66Equivalence Definition
- Two constraint stores are equivalent iff their
logical views are equivalent. - A statement produces a constraint store S iff
there is an execution of the statement without
garbage collection that terminates or suspends in
a state containing S. - A statement C completes a statement S iff the
execution of the sequence terminates
normally. - Two statements S1 S2 are equivalent iff for every
statement C completing both S1 and S2,
and produce equivalent stores.
67Equivalence Properties
- All stores produced by the same statement are
equivalent. - If the set of all statements in a statement
sequence is the same as the set of all statements
in another sequence, then the sequences are
equivalent. - The result of adding "thread ... end" to a
statement in any way allowed by the grammar is
equivalent to the original statement.
68Why use declarative models?
- Staying within a declarative model makes writing
correct programs much easier. - Declarative components are easier to combine and
thus more reusable. - There are no known declarative models fully
capable of dealing with the fact that the world
is not declarative. - But it is probably a good idea to localize the
use of non-declarative features as much as
possible.
69(No Transcript)
70CTM06
- Lecture 4A Constraint Model
71Model Merits
- Programmers specify problems declaratively as
constraints. Solutions satisfying the constraints
are found automatically. - Appealing constraint specification language that
can easily be extended from within the model. - Specialized efficient solver algorithms can be
added from within the model in an interoperable
manner. - The overall search strategies and heuristics can
easily be redefined from within the model.
72Model Demerits
- Hard to extend to new problem domains, because
the kind of constraints allowed in stores is
fixed. - Not completely declarative, due to some of the
extensibility features. However, as long as these
features are not misused, the model stays
declarative.
73Model Overview
- Extension of the concurrent declarative model
presented in the previous lecture. - Allows several constraint stores in each machine
state. - Associates each thread/stack to exactly one
store. A store and its threads is known as a
computation space. - Allows stores to contain domain constraints, each
of which constrains a single variable to some set
of values. - Provides suspension and notification triggered by
variable domain sizes. - Provides access to spaces and variable domains
from within the kernel language.
74Kernel Syntax Extensions
-
- FD.reflect.dom Variable ?DomainFD.watch.size
Variable N ?BoolFD.watch.min Variable N
?Bool - Space.is X ?BoolSpace.new Proc
?SpaceSpace.clone Space ?CloneSpace.merge
Space ?RootSpace.waitStableSpace.askVerbose
Space ?StatusSpace.commit Space
ChoiceSpace.choose NumChoices
?ChoiceSpace.inject Space Proc
75The Three Levels
- Basic constraints.
- Propagated constraints.
- Synthesized constraints.
76Basic Constraints (1)
- Basic constraints are the only constraints stored
directly in constraint stores. - They are stored as data structures linked to the
variables they constrain. - It is not possible to define new kinds of basic
constraints from within the model.
77Basic Constraints (2)
- X 33X 3X 3
- Y 37Z 2 5 1099
- W ZW compl(2 2040)
78Synthesized Constraints (1)
- A synthesized constraint is asserted in a
computation space by asserting an equivalent set
of simpler constraints. - Operators for asserting synthesized constraints
are defined as declarative procedures.
79Synthesized Constraints (2)
80Propagated Constraints (1)
- A propagated constraint exists in a space only by
being enforced by one or more threads belonging
to that space. Such threads are known as
propagators. - A propagator continuously produces basic
constraints entailed by the propagated constraint
in conjunction with the already existing basic
constraints. - A propagator should terminate when and only when
the propagated constraint is entailed by the
existing basic constraints. - A propagator must be sound, but is not required
to be complete. - Operators for asserting propagated constraints
are defined as procedures. They are supposed to
behave declaratively, although they often have to
use non-declarative features internally.
81Propagated Constraints (2)
- Browse X Y ZX Y Z 13
- Delay 2000FD.distinctD X Y Z
- Delay 2000X \ 2
- Delay 2000Y \ 2
82Propagator Example 1
- proc Conj X Y Z X Y Z 01
- thread if X 0 then Z 0 else Y
Z end end - thread if Y 0 then Z 0 else X
Z end end - thread if Z 1 then X 1 Y 1
end end - thread if X Y then Z X end
endend
83Propagator Example 2
- proc Conj X Y Z X Y Z 01
- thread cond X 0 then Z
0 X 1 then Y Z Y 0
then Z 0 Y 1 then X Z
Z 1 then X 1 Y 1 X Y then Z
X end endend
84Propagator Example 3 (1)
- proc NumDig X Y fun Len N if N
9 then 1 Len N div 10 else 1 end end
... proc Propagator1 ... end proc
Propagator2 ... endin Y 1(Len FD.sup
- 1) X 0FD.sup thread Propagator1
end thread Propagator2 endend
85Propagator Example 3 (2)
- proc Propagator1 Xsize FD.reflect.size
Xin Y Ydom FD.reflect.dom X if
FD.watch.size X Xsize then Propagator1 end
end - proc Propagator2 Ysize FD.reflect.size
Yin X Xdom FD.reflect.dom Y if
FD.watch.size Y Ysize then Propagator2 endend
86Propagator Example 3 (3)
- fun Ydom Xdom case Xdom of nil then
nil (AB)R then (Len
ALen B)Ydom R NR then Len
NYdom R endend
87Propagator Example 3 (4)
- fun Xdom Ydom case Ydom of nil then
nil (AB)R then (Min
AMax B)Xdom R NR then Min
NMax NXdom R endend
88Propagator Example 3 (5)
- fun Min Len fun Self Len Res if
Len 1 then Self Len-1 Res10 else Res end
endin if Len 1 then Self Len 1 else 0
endend - fun Max Len Min Len1 - 1end
89Space States
- A space is failed iff it contains inconsistent
basic constraints. - A space is entailed iff it is not failed and
contains no threads. - A space is stuck iff it is not failed and all
contained threads are suspended without any hope
of ever getting runnable again without external
intervention. - A space is unstable unless it is in any of the
above states.
90Propagation is not enough (1)
- Even if all involved propagators are complete, a
space may get stuck, because propagators are not
aware of each other. - Therefore a complete solver can not rely on the
use of a single computation space. - Hence the need for search and distribution...
91Propagation is not enough (2)
- X Y Z 13FD.distinctD X Y ZX
92Search Distribution (1)
- When a space is stuck, a guess has to be made in
order to resume propagation. - A thread known as a distributor is responsible
for constructing a set off possible guesses - For completeness, the disjunction of all possible
guesses should be entailed by the basic
constraints in the space. - To avoid repeated solutions, guesses should be
mutually exclusive.
93Search Distribution (2)
- The choice of which guess should be made is done
from outside the space by a search engine. - When the choice is made, the distributor asserts
the selected guess as a new constraint.
94Search Distribution (3)
- If the guess turns out to be wrong, it is
necessary to backtrack to a clone of the original
space without the guess. - This is done by the search engine.
- The search engine is also responsible for cloning
spaces as required for backtracking.
95Space Operations
- Space.is X ?Bool
- Space.new Proc ?Space
- Space.clone Space ?Clone
- Space.merge Space ?Root
- Space.waitStable
- Space.ask Space ?Status
- Space.commit Space Choice
- Space.choose NumChoices ?Choice
- Space.inject Space Proc
96A Simple Distributor
- proc Distribute Variables fun Self
Variables case Variables of nil
then skip XXs then if
FD.reflect.size X 1 then case
Space.choose 2 of 1 then
X FD.reflect.min X
2 then X \
FD.reflect.min X end
Self Variables else
Self Xs end end
endin thread Self Variables endend
97A Simple Search Engine
- fun Solve Problem fun Self S Res
case Space.ask S of failed then
Res succeeded then
Space.merge S Res alternatives(2)
then S2 Space.clone S in
Space.commit S 1
Space.commit S2 2 Self S2 Self S
Res end endin Self Space.new
Problem nilend
98Problem Example (1)
5 2 63 41
4 6 12 53
5 6 21 43
4 1 63 52
99Problem Example (2)
- Browse Solve MakeTriangleProblem 5
- Browse SearchAll MakeTriangleProblem 5
- Explorer.object script(MakeTriangleProblem 5)
100Problem Example (3)
- fun MakeTriangleProblem Width Size Width
(Width 1) div 2 ...in proc Base
Triangle in Triangle
MakeList Size Triangle 1Size
Nth Triangle Size-2 Size-1 FD.distinct Triangle
Constrain Triangle Width Distribute
Reverse Triangle Base List.take
Triangle Width endend
101Problem Example (4)
- proc Constrain Triangle Width if Width 1
then Top List.drop Triangle Width
in ConstrainBase Triangle Top Width
Constrain Top Width-1 endend - proc ConstrainBase XYYs ZZs Width
FD.distance X Y '' Z if Width 2 then
ConstrainBase YYs Zs Width-1 endend
102Space Inheritance (1)
- Whenever a new space is created, it becomes a
child of the space to which the creating thread
belongs. - A space may have at most one parent.
- A space may have any number of children.
- All threads, constraints and variables created by
a thread running in a space S will also belong to
S. - A thread running in a space S sees all and only
constraints and variables belonging to S or an
ancestor of S.
103Space Inheritance (2)
- proc Or C1 C2 S1 Space.new C1 S2
Space.new C2 - proc Loop Status case Status
of succeeded(entailed)_ then skip
_succeeded(entailed) then
skip failedfailed then
fail failed_ then
Space.merge S2 _ _failed then
Space.merge S1 _
suspended(X)suspended(Y) then Loop
XY endin thread Loop
Space.askVerbose S1Space.askVerbose S2
endend
104Space Inheritance (3)
- Browse X Y Z
- X 1099Y 12Z 39
- Or proc X FD.distance X Y '' Z end
105Epilogue on Prolog
- The extensibility of the Mozart system goes far
beyond what is provided by the Sicstus Prolog
system. - Prolog is based on resolution rather than
computation spaces. An annoying consequence of
this is that the order in which constraints are
asserted matters. - Conclusion Use Mozart instead of Prolog.
106(No Transcript)