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 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. 20 - Concurrent Logic Programming 1
06 25433 – Logic Programming Logic variable as information channel Remember – variables in Prolog are logic variables: • they cannot be re-instantiated; • they can be unified with Prolog terms, including uninstantiated variables. Better still - they can be – incrementally instantiated by more than one process contributing information. 20 - Concurrent Logic Programming 2
06 25433 – Logic Programming 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. 20 - Concurrent Logic Programming 3
06 25433 – Logic Programming 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. 20 - Concurrent Logic Programming 4
06 25433 – Logic Programming 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. 20 - Concurrent Logic Programming 5
06 25433 – Logic Programming Synchronization through shared variables - 4 This needs two changes to the language: Only when the guard 1 Guards tests have been plus(Augend, Addend, Sum) <- satisfied can the rule number(Augend), be committed to. number(Addend) | Sum is Augend + Addend. 20 - Concurrent Logic Programming 6
06 25433 – Logic Programming 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). Query: app([a,b], [1,2], List). Rule head: app([Hd|L1], L2, L3). Rule head: app([Hd|L1], L2, [Hd|L3]). 20 - Concurrent Logic Programming 7
06 25433 – Logic Programming 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. 1 2 Important idea: try 5 4 a many times until success. 3 20 - Concurrent Logic Programming 8
06 25433 – Logic Programming 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.. 1 2 Important idea: put off 5 4 a a choice until certain. 3 20 - Concurrent Logic Programming 9
06 25433 – Logic Programming Flat Concurrent Prolog There have been numerous proposals for concurrent logic programming languages: – Parlog – Guarded Horn Clauses (GHC) – Concurrent Prolog • Flat Concurrent Prolog guards are “normal” Prolog in -built predicates (mainly). 20 - Concurrent Logic Programming 10
06 25433 – Logic Programming merge/3 in FCP(|) merge/3 could equally be written in Prolog: Recursive Terminating: merge([X|In1],In2,Out) <- merge([],In,Out) <- Out = [X|Out1], In = Out. merge(In1,In2,Out1). merge(In,[],Out) <- explicit assignment In = Out. merge(In1,[X|In2],Out) <- because of 1-way Out = [X|Out1], unification merge(In1,In2,Out1). 20 - Concurrent Logic Programming 11
06 25433 – Logic Programming 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 order in which clauses were committed to. 20 - Concurrent Logic Programming 12
06 25433 – Logic Programming 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 other commitments were made. 20 - Concurrent Logic Programming 13
06 25433 – Logic Programming 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). 20 - Concurrent Logic Programming 14
06 25433 – Logic Programming 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: 2 i 3 j 5 k , 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. 20 - Concurrent Logic Programming 15
06 25433 – Logic Programming Hamming numbers - 2 We need to have an ordered merge process: omerge([X|In1], [Y|In2], Out) <- number(X), number(Y), X =:= Y | Out = [X|Out1], omerge(In1, In2, Out1). 20 - Concurrent Logic Programming 16
06 25433 – Logic Programming Hamming numbers - 3 omerge([X|In1], [Y|In2], Out) <- X gt Y | Out = [X|Out1], omerge(In1, [Y|In2], Out1). omerge([X|In1], [Y|In2], Out) <- Y gt X | Out = [Y|Out1], omerge([X|In1], In2, Out1). 20 - Concurrent Logic Programming 17
06 25433 – Logic Programming 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). 20 - Concurrent Logic Programming 18
06 25433 – Logic Programming 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), omerge(X2, X3, X23), omerge(X5, X23, Xs). 20 - Concurrent Logic Programming 19
06 25433 – Logic Programming 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. 20 - Concurrent Logic Programming 20
06 25433 – Logic Programming 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. 20 - Concurrent Logic Programming 21
06 25433 – Logic Programming 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 right. They cannot all eat at the same time. 20 - Concurrent Logic Programming 22
06 25433 – Logic Programming 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. 20 - Concurrent Logic Programming 23
06 25433 – Logic Programming 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. 20 - Concurrent Logic Programming 24
06 25433 – Logic Programming 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 20 - Concurrent Logic Programming 25
06 25433 – Logic Programming 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) 20 - Concurrent Logic Programming 26
Recommend
More recommend