06 25433 – Logic Programming
Concurrent Logic Programming
This lecture will cover: – synchronization through shared variables; – don’t care non-determinism; – reactive v. transformational systems.
Concurrent Logic Programming This lecture will cover: - - PowerPoint PPT Presentation
06 25433 Logic Programming Concurrent Logic Programming This lecture will cover: synchronization through shared variables; dont care non -determinism; reactive v. transformational systems. 06 25433 Logic Programming A new
06 25433 – Logic Programming
Concurrent Logic Programming
This lecture will cover: – synchronization through shared variables; – don’t care non-determinism; – reactive v. transformational systems.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 1
A new language
For concurrent programming, Prolog needs to be extended - or at least changed - to make it better suited. Changes are in three areas: – the logic variable as an information channel; – synchronization through shared variables; – viewing non-determinism differently.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 2
Logic variable as information channel
Remember – variables in Prolog are logic variables:
including uninstantiated variables. Better still - they can be – incrementally instantiated by more than one process contributing information.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 3
Synchronization through shared variables - 1
We need a way of suspending processes until they are ready to execute. Prolog would terminate catastrophically if both the first two arguments are uninstantiated:
plus(Augend, Addend, Sum) :- Sum is Augend + Addend.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 4
Synchronization through shared variables - 2
We can add some type checks so that the rule fails gracefully if the arguments are not instantiated to numerics:
plus(Augend, Addend, Sum) :- number(Augend), number(Addend), Sum is Augend + Addend.
but this doesn’t help in parallel processing where we need to delay execution until arguments are instantiated.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 5
Synchronization through shared variables - 3
If our language includes suspension, then we can synchronize processes quite easily. The idea is that a clause is: – immediately executable; – never executable; – possibly executable - dependent on changes to its arguments.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 6
Synchronization through shared variables - 4
This needs two changes to the language: 1 Guards
plus(Augend, Addend, Sum) <- number(Augend), number(Addend) | Sum is Augend + Addend.
Only when the guard tests have been satisfied can the rule be committed to.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 7
Synchronization through shared variables - 5
This needs two changes to the language: 2 One-way unification Prolog has 2-way unification - information flows both ways. We need information to flow one-way: Query: app([a,b], [1,2], List). Rule head: app([Hd|L1], L2, L3). Query: app([a,b], [1,2], List). Rule head: app([Hd|L1], L2, [Hd|L3]).
06 25433 – Logic Programming
20 - Concurrent Logic Programming 8
Alternative non-determinism - 1
Prolog uses “don’t know” non-determinism: – Programmer writes the (non-deterministic) program – Prolog searches for solution. – Programmer doesn’t know which path through the search tree has been taken.
a 1 3 4 2 5
Important idea: try many times until success.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 9
Alternative non-determinism - 2
We need to use “don’t care” non-determinism: – Programmer writes guarded clauses – OR-parallel search of heads & guards – One clause selected - either immediately or when unsuspended..
a 1 3 4 2 5
Important idea: put off a choice until certain.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 10
Flat Concurrent Prolog
There have been numerous proposals for concurrent logic programming languages: – Parlog – Guarded Horn Clauses (GHC) – Concurrent Prolog
guards are “normal” Prolog in-built predicates (mainly).
06 25433 – Logic Programming
20 - Concurrent Logic Programming 11
merge/3 in FCP(|)
merge/3 could equally be written in Prolog: Terminating:
merge([],In,Out) <- In = Out. merge(In,[],Out) <- In = Out.
explicit assignment because of 1-way unification Recursive
merge([X|In1],In2,Out) <- Out = [X|Out1], merge(In1,In2,Out1). merge(In1,[X|In2],Out) <- Out = [X|Out1], merge(In1,In2,Out1).
06 25433 – Logic Programming
20 - Concurrent Logic Programming 12
Running merge/3 in FCP(|) - 1
fcp(|) ?- merge([1,2],[a,b],List). Variable bindings: *** List=[a,1,b,2] *** Suspended goals ***
Note the order of elements shows the
were committed to.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 13
Running merge/3 in FCP(|) - 2
fcp(|) ?- merge([1,2],[a,b],List). Variable bindings: *** List=[a,1,2,b] *** Suspended goals ***
The order of elements is different because
were made.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 14
Running merge/3 in FCP(|) - 3
merge/3 in Prolog would be OR-unfair - it would always favour one choice of clause over any other. This implementation of FCP(|) is OR-fair because it makes a arbitrary selection from candidate clauses. Any executable clause will eventually fire (in theory and given eternity).
06 25433 – Logic Programming
20 - Concurrent Logic Programming 15
Hamming numbers - 1
merge/3 isn’t a good example of a concurrent program because a fair version could be written quite easily in Prolog. Hamming numbers are an ordered stream of numbers in the form: 2i3j5k, e.g.[1,2,3,4,5,6,8,9,10,12,15,…]. It is possible to write this in Prolog - but easier in FCP.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 16
Hamming numbers - 2
We need to have an ordered merge process:
number(X), number(Y), X =:= Y | Out = [X|Out1],
06 25433 – Logic Programming
20 - Concurrent Logic Programming 17
Hamming numbers - 3
X gt Y | Out = [X|Out1],
Y gt X | Out = [Y|Out1],
06 25433 – Logic Programming
20 - Concurrent Logic Programming 18
Hamming numbers - 4
We also have to be able to multiply a list of numbers by a given number:
multiply([X|In], N, Out) <- Out = [Y|Out0], Y := X * N, multiply(In, N, Out0).
06 25433 – Logic Programming
20 - Concurrent Logic Programming 19
Hamming numbers - 5
Finally we need to add the top-level rule:
hamming(Xs) <- multiply([1|Xs], 2, X2), multiply([1|Xs], 3, X3), multiply([1|Xs], 5, X5),
06 25433 – Logic Programming
20 - Concurrent Logic Programming 20
Hamming numbers - 6
Seeing the output is more difficult because the process runs continually. It is a good example of a reactive system - which reacts to input and continues. merge/3 is an example of a transformational system - which transforms its input into an output.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 21
What happened to mutual exclusion?
Sometime we need to ensure that only one process has access to a resource (e.g. file, screen, keyboard input) - and all others are excluded. Simple mutual exclusion is fairly easy by setting variables shared between processes. Hard mutual exclusion is impossible in FCP(|) - but not other concurrent logic programming languages.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 22
The Dining Philosophers - 1
Imagine five philosophers sitting around a circular table. Their meal is an endless supply of slippery spaghetti It requires the use of two forks to eat it. They are too poor to own more than one fork which they place on the table on their left-hand side. If they are to avoid hunger, they have to co-operate and use their fork and the one belonging to the philosopher to their
06 25433 – Logic Programming
20 - Concurrent Logic Programming 23
The Dining Philosophers - 2
The problem is that there is no way of excluding groups of resources in FCP(|). We can’t grab two forks simultaneously and relinquish two forks simultaneously. We just need a more powerful programming language - strictly speaking, one with atomic unification.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 24
The model: stream parallelism
FCP (and most other concurrent logic programming languages) use stream parallelism. – goal/subgoal calls are evaluated concurrently; – communication is through shared variables; – as this is logic programming, the shared variable is a logic variable; – the variable is used for every communication - data and synchronization. We almost have to have don’t care non-determinism.
06 25433 – Logic Programming
20 - Concurrent Logic Programming 25
Looking back at the module
Major themes: Logic programming languages are based on models from predicate logic. They all have to deal with: OR-choice AND-choice
06 25433 – Logic Programming
20 - Concurrent Logic Programming 26
Looking back at the module
Major themes: OR-choice involves non-determinism Non-determinism comes in several varieties – e.g. Don’t know (using a stack – Prolog and friends) Don’t care (pick one; throw away the rest – FCP etc)
06 25433 – Logic Programming
20 - Concurrent Logic Programming 27
Looking back at the module
Major themes: Variables (sometimes with constraints) Logic programming has a distinctive model of variable Two-way unification – like Prolog and CLP One-way unification – like FCP and ConLP Incomplete information – all LP languages