1 Membrane Computing in Prolog Mihaela Malita University of Bucharest, Faculty of Mathematics Email: malita@sunu.rnc.ro Abstract This paper presents a Prolog program that simulates the Computing with Membranes proposed by Gheorghe Paun in November 1998 at Turku /1/. We present from /1/ the concept of membrane, membrane structure, and the super cell system in our list representation for the program. The program was tested on the examples from /1/. The simulator is conceived to be useful for developing applications which might test the power of this new computing paradigm. 1. Multisets in Prolog. Basic Operations The Membrane Computation proposed by Gheorghe Paun /1/ seems to be an interesting and original approach to computing inspired from biology. Meantime this new paradigm captured the attention of many researchers (J.Dassow/3/, G.Rozenberg/4/, A.Salomaa/4/, A.Atanasiu/2/). When we define a new concept the question arises: "which is the most appropriate representation for it?". The membrane, membrane structure and supercell system are new concepts P`un /1/. The membrane starts from the concept of multiset. In the following we present this concepts in the list representation. Representation of a multiset. A multiset is a set where we admit multiple occurrences of the objects. In Prolog we shall represent a multilist as a list of objects with their frequencies (multiplicities). Example. {a,a,b,c,c,c} is in Prolog: [a(2),b(1),c(3)] multiset(Ms). Tests if a list Ms is a Multiset. ?- multiset([a(1),b(2),c(4)]). yes object(_(_)). multiset([]). multiset([H|T]):-object(H),multiset(T). multiplicity(Object,Muliset). The multiplicity of an object from a multiset is the occurrences of the object. ?-multiplicity(a,[a(2),b(3),c(8)],M). M=2 multiplicity(H,Ms,R):-on(H(R),Ms),!. Usually objects that have multiplicity 0 are of no use and we can delete then from the list. mult_zero(_(0)). Support of a multiset is the set (ignoring the multiplicity). support(MS,R). From the multiset Ms we select the objects without their The resulting set is R. ?- support([a(2),b(3),c(8)],R). R=[a,b,c] support([],[]). support([H(_)|T],[H|R]):- support(T,R). multiplicities. Inclusion of multisets. X is included in Y if all the objects from X are also in Y and their multiplicity is smaller or equal than their multiplicity in Y. include(X,Y). Returns yes if X Y else no. ?- include([a(2),b(3)],[a(3),b(4),c(7)]). yes include([],_). include([H(R1)|T],L):- on(H(R2),L),R1=<R2,include(T,L). 2 Union of multisets. The union of two multisets is a multiset which all the objects form X and Y and their multiplicity is the sum of their multiplicity in X and Y. union(X,Y,R). X Y = R ?- union([a(2),b(3)],[a(4),c(8)],R). R=[a(6),b(3),c(8)] union([],Y,Y). union([H(R1)|T],Y,[H(R)|S]):- append(Y1,[H(R2)|Y2],Y),R is R1+ R2, concat(Y1,Y2,Ynou),union(T,Ynou,S),!. union([H(R1)|T],Y,[H(R1)|S]):- union(T,Y,S). Difference of multisets. The difference is defined only if the multisets are included one in another. The difference is a multiset with the objects from M1 and their multiplicity is the difference between the multiplicity in M1 and the corresponding multiplicity in M2. difference(M1,M2,Dif). M1 - M2 = Dif ?- difference([a(2),b(3),c(3)],[a(2),b(1)],R). R=[b(2),c(3)]. ?- difference([a(2),b(3)],[a(2),b(3)],R). R=[]. ?- difference([a(2),b(3)],[b(5)],R). no difference(Y,[],Y):- !. difference(Y,[H(R2)|T],RR):- append(Y1,[H(R1)|Y2],Y), R1 >= R2, R is R1-R2, concat(Y1,Y2,Ynou),difference(Ynou,T,S), (R = 0, RR=S,!; R > 0, RR=[H(R)|S]). 2. The Membrane Structure in Prolog The concept of Membrane structure as it is presented in Gh. Paun /1/. Let's take actually his first example: A membrane structure is formed from multisets which are included one in another. The multisets are not allowed to have any intersection. They are disjoint or included one in another. A possible representation of the multiset form /1/ is: Mem= [a,a,c,[a,[c,d]],[]] The representation that we shall use is: Mem=[a(2),c(1),[a(1),[c(1),d(1)]],[]] The membranes have names (numbers), so we could refer them in the membrane structure. Let's put numbers in the front of each sublist. Each sublist represents a membrane. Mem=[1,a(2),c(1),[2,a(1),[3,c(1),d(1)]],[4]] Let's try to work with this representation. Advantages: - the list structure respects the initial topology of the membrane. - the membranes marked with numbers (different!). In the following we use the same classical append(L1,L2,R): append([],Y,Y). append([H|T],Y,[H|R]):- append(T,Y,R). membrane(Nr,Ms,Mnr). The content of membrane with number K from the membrane structure. The membrane with number K from the membrane structure exclusively the content of membrane K. ?-membrane(2,[1,a(2),[2,a(3),b(4),[3,f(1),j(7)]]],[4]],R). R=[a(3),b(4)] ?-membrane(4,[1,a(2),[2,a(3),b(4),[3,f(1),j(7)]]],[4]],R). R=[] ?-membrane(5,[1,a(2),[2,a(3),b(4),[3,f(1),j(7)]]],[4]],R). no object(_(_)):-!. object(X):- atomic(X),not X=[]. membrane(K,[K|T],R):- select_p(object,T,R),!. 3 membrane(K,[H|T],R):- not atomic(H),membrane(K,H,R). membrane(K,[H|T],R):- membrane(K,T,R). disolve(K,Mem,R). Dissolve the membrane K of Mem. The resulting membrane R is in R. To dissolve a membrane all its content is poured into the membrane in which it is contained (included). And the membrane disappears. In a list representation that means the brackets of the membrane are removed. If nothing could be dissolved then the function returns the membrane ?-disolve(2,[1,a(2),c(1),[2,a(1),[3,c(1),d(1)]],[]],R). R=[1,a(2),c(1),a(1),[3,c(1),d(1)],[4]] ?-disolve(3,[1,a(1),[2,c(2),[3,c(2)]]],R). R=[1,a(1),[2,c(4)]] ?-disolve(4,[1,a(1),[2,b(2),[3,c(2)]]],R). R=[1,a(1),[2,b(2),[3,c(2)]]] disolve(K,[],[]):-!. disolve(K,M,R):- append(M1,M2,M),append([[K|T]],Ig,M2), concat(M1,T,R1),concat(R1,Ig,R),!. disolve(K,[H|T],[H|Tr]):- atomic(H),disolve(K,T,Tr),!. disolve(K,[H|T],[Hr|Tr]):- disolve(K,H,Hr),disolve(K,T,Tr). where_is(K,Ms,N). We want to know the number N of the membrane that is in teh membrane structure Ms and includes the membrane K. ?- where_is(3,[1,a(1),[2,b(3),[3]],[4]],I). R=2 ?- where_is(5,[1,a(1),[2,b(3),[3]],[4]],I). no where_is(K,[],_):- fail. where_is(K,[H|T],H):- number(H),on([K|_],T),!. where_is(K,[H|T],R):- atom(H),where_is(K,T,R). where_is(K,[H|T],R):- where_is(K,H,R),! ; where_is(K,T,R),!. transf(K,New,Ms,R). Transform Membrane structure Ms by replacing the membrane number K with membrane New. The resulting membrane structure is R. ?-transf(2,[b(3)],[1,a(2),c(1),[2,a(1),[3,c(1),d(1)]],[4]],R) R= [1,a(2),c(1),[2,b(3),[3,c(1),d(1)]],[4]] ?-transf(5,[b(3)],[1,a(2),[2,[3,c(1),d(1)]],[4]],R) no transf(K,New,[],[]):-!. transf(K,New,[K|T],[K|R]):- delete_p(object,T,Tr),concat(New,Tr,R),!. transf(K,New,[H|T],[H|R]):- (object(H) ; number(H)),transf(K,New,T,R),!. transf(K,New,[H|T],[Hr|Tr]):- transf(K,New,H,Hr),transf(K,New,T,Tr). 3. The Super Cell System The super cell system is a membrane structure with rules /1/. The membrane structure evolves according to the rules. The rules are applied in parallel for each membrane. In /1/ Gh. Paun presents some of types of rules. We implemented the them in 3.2. The Prolog language is fit for dealing with rules. This made our approach convenient. In the following we present some necessary predicates used in the program not specially connected with the membrane calculus. 3.1 Necessary predicates subst_all(V,N,Old_list,New_list). Substitutes on all levels in Old_list the old object V by the new object N. ?- subst_all(x,y,[1,a(1,x),[2,b(1,x]]). R= [1,a(1,y),[2,b(1,y]] subst_all(V,N,X,X):- atomic(X),!. subst_all(V,N,O(X,Y),O(X,Y)):- not Y=V,!. 4 subst_all(V,N,[O(F,V)|T],[O(F,N)|R]):- subst_all(V,N,T,R),!. subst_all(V,N,[H|T],[R1|R2]):- subst_all(V,N,H,R1),subst_all(V,N,T,R2). select_p(P,List,R). Selects all the elements from a list (first level) which have a certain property P. ?- select_p(object,[1,a(1),c(4),[2,b(3)]],I). I=[a(1),c(4)] select_p(P,[],[]):- !. select_p(P,[H|T],[H|R]):- P(H),select_p(P,T,R). select_p(P,[H|T],R):- select_p(P,T,R). delete_p(P, List). Deletes all objects from the first level of the list L that have property P. ?- delete_p(integer,[2,a,3,b],R). R=[2,3] ?- delete_p(mult_zero,[a(2),d(0),b(0),c(7)],R). R=[a(2),c(7)] delete_p(P,[],[]). delete_p(P,[X|T],R):- P(X),delete_p(P,T,R),!. delete_p(P,[X|T],[X|R]):- delete_p(P,T,R). append([],Y,Y). append([H|T],Y,[H|R]):- append(T,Y,R). 3.2 Basic Operations in a Membrane Structure In the program a multiset is an object that looks like: a(1,x) or c(1,y). We shall explain later why we introduced the markers x and y for each object. This small modification obliged us to rewrite the main operations on multisets and membranes. union(M1,M2,R). R is the union of membranes M1 and M2. It follows the same pattern as the union in multisets. ?- union([a(2,x),b(3,x)],[a(1,x),b(1,y)],R). R=[a(3,x),b(3,x)],b(1,y)] union([],Y,Y). union([H(R1,K1)|T],Y,[H(R,K1)|S]):- append(Y1,[H(R2,K1)|Y2],Y),R is R1+ R2, concat(Y1,Y2,Ynou),union(T,Ynou,S),!. union([H(R1,K)|T],Y,[H(R1,K)|S]):- union(T,Y,S). difference(M1,M2,D). D is the difference of membranes. It follows the same pattern as in multisets. If the multisets (membranes) are not included one in another the difference is not possible (fails). ?- difference([a(2,x),b(3,x),c(3,x)],[a(2,x),b(1,x)],R). R=[b(2,x),c(3,x)]. ?- difference([a(2,x),b(3,x)],[a(2,x),b(3,x)],R). R=[]. ?- difference([a(2,x),b(3,x)],[b(2,y)],R). no difference(Y,[],Y):- !. difference(Y,[H(R2,Mark)|T],RR):-append(Y1,[H(R1,Mark)|Y2],Y), R1 >= R2, R is R1-R2, concat(Y1,Y2,Ynou),difference(Ynou,T,S), (R = 0, RR=S,!; R > 0, RR=[H(R,Mark)|S]). membrane(Nr,Ms,Mnr). Mnr will be the content of membrane with number K from the membrane structure Ms (exclusively the content of membrane K). ?-membrane(2,[1,a(2,x),[2,a(3,x),b(4,x),[3,f(1,x),j(7,x)]]],[4]],R). R=[2,a(3,x),b(4,x)] membrane(K,[K|T],R):- select_p(object,T,R),!. 5 membrane(K,[H|T],R):- not atomic(H),membrane(K,H,R). membrane(K,[H|T],R):- membrane(K,T,R). disolve(K,Mem,Rez). Dissolve the membrane K in the membrane structure Ms. The resulting membrane structure is R. ?-disolve(3,[1,a(1,x),[2,c(2,x),[3,b(1,x)]]],R). R=[1,a(1,x),[2,c(2,x),b(1,x)]] disolve(K,[],[]):- !. disolve(K,M,R):- append(M1,M2,M),append([[K|T]],Ig,M2), concat(M1,T,R1),concat(R1,Ig,R),!. disolve(K,[H|T],[H|Tr]):- object(H),disolve(K,T,Tr),!. disolve(K,[H|T],[Hr|Tr]):- disolve(K,H,Hr),disolve(K,T,Tr). where_is(K,Ms,X). We want to know the number of the membrane that and includes K in the Membrane structure Ms. ?- where_is(4,[1,a(1),[2,b(3),[3]],[4]],I). R=1 where_is(K,[],_):- fail. where_is(K,[H|T],H):- number(H),on([K|_],T),!. where_is(K,[H|T],R):- atom(H),where_is(K,T,R). where_is(K,[H|T],R):- where_is(K,H,R),! ; where_is(K,T,R),!. sintez(Ms,R). Ms is a membrane structure where different objects may appear several times with different frequencies. We want each object to appear only once with the sum of all frequencies. ?-sintez([1,a(1,x),c(1,x),a(1,x),[2,b(2,x),b(2,x)]],R). R=[1,a(3,x),c(1,x),[2,b(4,x)]] sintez([],[]):-!. sintez([N|T1],[N|T2]):- integer(N),sintez(T1,T2),!. sintez([O(F,Y)|T1],[O(F,Y)|T2]):- not on(O(_,_),T1),sintez(T1,T2),!. sintez([O(F,Y)|T1],R):- append(X,[O(Fnew,Y)|Rest],T1), Fr is Fnew + F, concat(X,[O(Fr,Y)|Rest],T),sintez(T,R). sintez([H|T],[Hr|Tr]):- sintez(H,Hr),sintez(T,Tr),!. transf(K,New,Ms,R). We have the new membrane K and replace the old one Transform Membrane structure that is we replace the old membrane let say K with a new membrane New in the membrane structure Ms. The resulting membrane structure is Ms. ?-transf(2,[b(3,x)],[1,a(2,x),c(1,x),[2,a(1,x),[3,c(1,x),d(1,x)]],[4]],R) R= [1,a(2,x),c(1,x),[2,b(3,x),[3,c(1,x),d(1,x)]],[4]] object(_(_,_)):-!. object(X):- atomic(X),not X=[]. transf(K,New,[],[]). transf(K,New,[K|T],[K|R]):- delete_p(object,T,Tr),concat(New,Tr,R),!. transf(K,New,[H|T],[H|R]):- (object(H) ; number(H)),transf(K,New,T,R). transf(K,New,[H|T],[Hr|Tr]):- transf(K,New,H,Hr),transf(K,New,T,Tr). 3.3 The rules of a Super Cell System A membrane structure which has rules concerning the mobility of the objects is called Super Cell System /1/. The rules are of different types. We shall take in consideration only the rules that appear in the examples from /1/. For membrane 1 this rule is presented: (1) c -> [in(4),a] This means the number of the rule is 1 and it is applicable only for membrane 1. If membrane 1 has a c inside, then the c is moved and an object appears in membrane 4. We write this rule in our data file as: rule(1,1,[c(1,x)],[in(4),a(1,y)]). The first 1 is the number of the membrane. The second 1 is the number of the rule. 6 We shall mark each rule by a number. Then is the list of objects that are moved from membrane 1. The Super Cell System is a parallel machine. The rules are applied simultaneously. In this version our solution to simulate the parallelism is to mark the objects that appear in one with y. For rule 1,1 we have to mark the new objects that appear by y (this is our choice). So c(1,x) -> [in(4),a(1,y)]. All the objects that appear in the right part of a rule are marked with y. This gives the possibility to make the difference between the new object and the old one in order not to apply at the same clock a rule on a new object. We could also have a rule like that (1) c,c,b -> [in(4),a] Our representation is: rule(1,2,[c(2,x),b(1,x)],[in(4),a(1,y)]). That means if membrane 1 contents two c's and b we take them and in membrane 4 we put an a. We could also have a rule for the same membrane: (4) b -> a This means in membrane 4 we could change b with a. Actually all the b's are transformed in a's. Another principle is: If a rule works for a membrane we apply the rule until it works no more. We could also dissolve membrane. If membrane 2 has a(2) and c inside, then delete the membrane. The content of the membrane is poured into the upper membrane. (2) aac -> disolve Our representation: rule(2,2,[a(1,x),c(1,x)],disolve). We could also throw out an object. This means the object is moved in the upper membrane (the "immediate" membrane which contains membrane 4): (4) c -> [out,d]. rule(4,1,[c(1,x)],[out,d(1,y)]). Let's take now each rule and see how it works. Following the Prolog program. All the rules are applied with the predicate apply(rule(membraneNr,RuleNr,Multiset,List), Ms,R). R is the resulting membrane structure after applying the rule (..) on the membrane structure Ms. rule(K,RuleNr,Mset,disolve). If there is in the membrane structure a membrane K then disolve membrane K, after we take Mset from it. Examples: rule(2,2,[a(1,x),c(1,x)],disolve). rule(3,1,[a(1,x)],disolve). ?- apply(rule(2,1,[a(1,x)],disolve),[1,b(1,x),[2,a(2,x),[3]],[4]],R). R=[1,b(1,x),a(1,y),[3],[4]] apply(rule(K,_,Mset,disolve),Ms,R):- membrane(K,Ms,Mk), difference(Mk,Mset,New),modify_x(New,Newy),transf(K,Newy,Ms,Ms1), disolve(K,Ms1,R),!,retractall(rule(K,_,_,_)). rule(K,RuleNr,Mset,[disolve,ob(N,I),...]). If there is Mset in membrane K then dissolve membrane K, after you take Mset from it. Examples: rule(2,2,[c(1,x),a(1,x)],[disolve,d(1,y)]). ?- apply(rule(2,_,[a(1,x)],[disolve,b(1,y)]),[1,b(1,x),[2,a(2,x),[3]],[4]],R). R=[1,b(1,x),a(2,y),[3],[4]] apply(rule(K,_,Mset,[disolve|List]),Ms,R):- membrane(K,Ms,Mk),difference(Mk,Mset,New), union(New,List,U1),transf(K,U1,Ms,Ms1),disolve(K,Ms1,R),!,retractall(rule(K,_,_,_)). 7 rule(K,RuleNr,Mset,out). If membrane K and has inside the multset Mset then throw Mset out. That means that two membranes modify their content: membrane K and the membrane that includes K. The topology remains the same. Examples: rule(4,1,[c(1,x),d(1,x)],out). ?-apply(rule(2,[a(1,x)],out),[1,a(3,x),c(1,x),[2,a(2,x),[3,d(1,x)]]],R). R=[1,a(4,x),c(1,x),[2,a(1,x),[3,d(1,x)]]] apply(rule(K,_,Mset,out),Ms,R):- membrane(K,Ms,Mk),difference(Mk,Mset,D1), where_is(K,Ms,X),membrane(X,Ms,Mx),modify_x(Mset,Mset2), union(Mx,Mset2,Newx),transf(X,Newx,Ms,Ms1),transf(K,D1,Ms1,R),!. rule(K,RuleNr,Mset,[out|List]). We take an object O(N,_) from membrane K and throw it out. That means that two membranes modify their content. The membrane K and the membrane that includes K. The topology remains the same. Applying the rule on the Membrane Structure the function returns the new Membrane Structure. Example: rule(4,1,[c(1,x)],[out,d(1,y)]). ?-apply(rule(2,[a(1,x)],[out,b(1,y)]),[1,a(3,x),[2,a(2,x),[3,d(1,x)]]],R). R=[1,a(3,x),b(1,y),[2,a(1,x),[3,d(1,x)]]] apply(rule(K,_,Mset,[out|List]),Ms,R):- membrane(K,Ms,Mk),difference(Mk,Mset,D1), where_is(K,Ms,X),membrane(X,Ms,Mx),union(Mx,List,Newx), transf(X,Newx,Ms,Ms1),transf(K,D1,Ms1,R),!. rule(K,RuleNr,Mset,[in(N)|MsetNew]). If membrane K contains the multiset Mset then we take Mset from it and put MsetNew in membrane N. Example: rule(1,1,[c(1,x)],[in(4),a(1,y),b(2,y)]). ?-apply(rule(2,1,[a(1,x)],[in(3),a(1,y),d(2,y)]), [1,a(2,x),c(1,x),[2,a(1,x),[3,c(1,x)]],[4]],R). R=[1,a(2,x),c(1,x),[2,[3,a(1,y),c(1,x),d(2,y)]],[4]] apply(rule(K,_,Mset,[in(NrM)|List]),Ms,R):- membrane(K,Ms,Mk),membrane(NrM,Ms,Mnr), difference(Mk,Mset,Newk),union(Mnr,List,NewNr), transf(K,Newk,Ms,Ms1),transf(NrM,NewNr,Ms1,R),!. rule(K,Mset,[[in(K1),Ob(Freq,y),..],[in(K2),Ob(Freq,y),..],[Ob(Freq,y),..]). This is a little bit more complex. It is a combination of two types of rules. If in membrane K we find the multiset Mset, then we take Mset from it and in each membrane K1, K2,.. we put the corresponding list of objects. If the list has no number in front that is there is no in(N) then this means we put the following objects in the same membrane that is K. Example: rule(1,3,[a(1,x)],[[in(2),a(1,y)],[b(1,y)]]). ?-apply(rule(2,3,[a(1,x)],[[in(3),a(1,y)],[b(1,y)]]), [1,d(1,x),[2,a(1,x),[3,c(1,x),d(1,x)]],[4]],R). R= [1,d(1,x),[2,b(1,y),[3,a(1,y),c(1,x),d(1,x)]],[4]],R). ?-apply(rule(1,4,[a(1,x)],[[in(3),b(1,y)],[in(4),c(1,y)]), [1,a(1,x),[2,d(2,x),[3]],[4]],R). R= [1,[2,d(2,x),[3,b(1,y)]],[4,c(1,y)]],R). apply(rule(K,_,Mset,[[H|T]|List]),Ms,R):- membrane(K,Ms,Mk),difference(Mk,Mset,D1), transf(K,D1,Ms,Rk),collect_union(K,[[H|T]|List],Rk,R),!. collect_union(K,[],Ms,Ms):-!. collect_union(K,[[H|T]|List],Ms,RR):- (H=in(I),membrane(I,Ms,Mi),union(Mi,T,Newi), transf(I,Newi,Ms,R1),collect_union(K,List,R1,RR)),!; (not H=in(_),membrane(K,Ms,Mk),union(Mk,[H|T],Newk), transf(K,Newk,Ms,R1),collect_union(K,List,R1,RR)). 8 rule(K,RuleNr,Mset,List). This is the case of changing in the same membrane K the multiset Mset with the multiset List. Example: rule(4,2,[b(1,x),d(2,x)],[a(1,y),c(2,y)]). ?-apply(rule(2,3,[b(1,x)],[c(1,y),d(2,y)]), [1,a(2,x),[2,b(1,x),[3,d(1,x)]],[4]],R). R=[1,a(2,x),[2,c(1,y),d(2,y),[3,d(1,x)]],[4]],R). apply(rule(K,_,Mset,[X|List]),Ms,R):- not X=in(_),not X=out, not X=disolve, membrane(K,Ms,Mk),difference(Mk,Mset,D1), union(D1,[X|List],New),transf(K,New,Ms,R),!. As we seen before each apply(rule(MemNr,RuleNr,Mset,List),Ms,R) applies the rule only once with the predicate try(K,No,Ms,RR) we try to apply the rule(K,No,_,_) on the membrane, structure Ms. The resulting membrane structure is RR. try(K,No,Ms,RR). Try rule [K,No] until it is no more appliable on membrane structure Ms. try(K,No,Ms,RR):- rule(K,No,X,Y),apply(rule(K,No,X,Y),Ms,R1), write('Rule='),write([K,No]),write(X),write('->'),write(Y),nl, write('OLD= '),write(Ms),nl, write('SUCCEEDED! New='),write(R1),nl,new(change), assert(succeeded(K,No)),try(K,No,R1,RR). try(K,No,Ms,Ms):- !. The Super Cell System has a clock. The clock starts with 1 and is incremented by 1. We call a generation the resulting configuration of the membrane structure after we applied all the possible rules in a clock. clock(0). new(Contor):- Contor(K),X is K+1, retract(Contor(K)),assert(Contor(X)). start. This is the main predicate. ?- start. .. listing from section &3 start:- write('File name for Super Cell= '),read(File), consult(File), write('Rules are '),nl,listing(rule), write('Order of the rules is'),nl,listing(order), write('How many generations?='),read(Gen), nl,write('Membrane is '),mstructure(M),write(M),nl, again(M,Gen). again(M,Gen):- new(clock),clock(C),nl,write('Clock='),write(C),nl, retractall(change(_)),assert(change(0)), retractall(succeeded(_,_)),assert(succeeded(0,0)), retractall(tried(_,_)),assert(tried(0,0)), write('Membrane='), write(M),nl, generation(C,M,R),write('Result='),write(R),nl, modify_y(R,Rx), (change(X),not X=0, C < Gen, again(Rx,Gen) ; true). We choose only one rule that works successful for a membrane. So if the rule [1,1] worked we don't try another rule for membrane 1 in this clock. If rule [1,1] does not succeed we try another rule guided by order(MembraneNr,RuleNr1,RuleNr2). generation(C,M,RR):- rule(K,N,_,_),not succeeded(K,_),not tried(K,N), not better_rule(K,N),assert(tried(K,N)), try(K,N,M,R),generation(C,R,RR). generation(C,M,M):- !. list_of_rules(Rules). In the list Rules we find all the rules of the Super Cell we are working with. We assume in our program that the each rule has a number. ?- list_of_rules(R). R=[[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[3,1],[4,1],[4,2]] 9 list_of_rules(R):- findall([I,K],rule(I,K,_,_),R). better_rule(K,N). Let's see if rule [K,N] has a better rule in front, that is a rule of higher order which is not tried yet. The answer is yes or no. better_rule(K,N):- order(K,N1,N),not tried(K,N1). modify_x(Membrane_structure, Result). Substitutes all x in the membrane structure by y. We need this in order to simulate the parallelism. We need to unmark the objects (substitute y in x back) when another generation begins. ?- modify_x([1,a(1,x),[2,b(1,x),c(1,x)],[3]],R). R= [1,a(1,y),[2,b(1,y),c(1,y)],[3]] ?- modify_y([1,a(1,x),[2,c(1,x),c(1,y)],[3]],R). R= [1,a(1,x),[2,b(1,x),c(2,x)],[3]] modify_y(R,RR):- subst_all(y,x,R,Rx),sintez(Rx,RR). modify_x(R,RR):- subst_all(x,y,R,Ry),sintez(Ry,RR). 3.4 An example of running the program The program is entirely the collection of predicates presented in section 3 before. Here is the first example from Paun /1/. The super cell system is described in the file called paun1.dec. This is the listing of the program after ?- start. File name for Super Cell= paun1 rule(1,1,[c(1,x)],[in(4),c(1,y)]). rule(1,2,[c(1,x)],[in(4),b(1,y)]). rule(1,3,[a(1,x)],[[in(2),a(1,y)],[b(1,y)]]). rule(1,4,[d(2,x)],[in(4),a(1,y)]). rule(2,1,[a(1,x)],[in(3),a(1,y)]). rule(2,2,[a(1,x),c(1,x)],disolve). rule(3,1,[a(1,x)],disolve). rule(4,1,[c(1,x)],[out,d(1,y)]). rule(4,2,[b(1,x)],[b(1,y)]). Order of the rules is order(1,1,3). order(1,2,3). How many generations?= 4 Membrane is [1,a(2,x),c(1,x),[2,a(1,x),[3,c(1,x),d(1,x)]],[4]] Clock=1 Membrane=[1,a(2,x),c(1,x),[2,a(1,x),[3,c(1,x),d(1,x)]],[4]] Rule=[1,1][c(1,x)]->[in(4),c(1,y)] OLD= [1,a(2,x),c(1,x),[2,a(1,x),[3,c(1,x),d(1,x)]],[4]] SUCCEEDED! New=[1,a(2,x),[2,a(1,x),[3,c(1,x),d(1,x)]],[4,c(1,y)]] Rule=[2,1][a(1,x)]->[in(3),a(1,y)] OLD= [1,a(2,x),[2,a(1,x),[3,c(1,x),d(1,x)]],[4,c(1,y)]] SUCCEEDED! New=[1,a(2,x),[2,[3,c(1,x),d(1,x),a(1,y)]],[4,c(1,y)]] Result=[1,a(2,x),[2,[3,c(1,x),d(1,x),a(1,y)]],[4,c(1,y)]] Clock=2 Membrane=[1,a(2,x),[2,[3,c(1,x),d(1,x),a(1,x)]],[4,c(1,x)]] Rule=[1,3][a(1,x)]->[[in(2),a(1,y)],[b(1,y)]] OLD= [1,a(2,x),[2,[3,c(1,x),d(1,x),a(1,x)]],[4,c(1,x)]] SUCCEEDED! New=[1,a(1,x),b(1,y),[2,a(1,y),[3,c(1,x),d(1,x),a(1,x)]],[4,c(1,x)]] Rule=[1,3][a(1,x)]->[[in(2),a(1,y)],[b(1,y)]] OLD= [1,a(1,x),b(1,y),[2,a(1,y),[3,c(1,x),d(1,x),a(1,x)]],[4,c(1,x)]] SUCCEEDED! New=[1,b(2,y),[2,a(2,y),[3,c(1,x),d(1,x),a(1,x)]],[4,c(1,x)]] Rule=[3,1][a(1,x)]->disolve OLD= [1,b(2,y),[2,a(2,y),[3,c(1,x),d(1,x),a(1,x)]],[4,c(1,x)]] SUCCEEDED! New=[1,b(2,y),[2,a(2,y),c(1,y),d(1,y)],[4,c(1,x)]] 10 Rule=[4,1][c(1,x)]->[out,d(1,y)] OLD= [1,b(2,y),[2,a(2,y),c(1,y),d(1,y)],[4,c(1,x)]] SUCCEEDED! New=[1,b(2,y),d(1,y),[2,a(2,y),c(1,y),d(1,y)],[4]] Result=[1,b(2,y),d(1,y),[2,a(2,y),c(1,y),d(1,y)],[4]] Clock=3 Membrane=[1,b(2,x),d(1,x),[2,a(2,x),c(1,x),d(1,x)],[4]] Rule=[2,2][a(1,x),c(1,x)]->disolve OLD= [1,b(2,x),d(1,x),[2,a(2,x),c(1,x),d(1,x)],[4]] SUCCEEDED! New=[1,b(2,x),d(1,x),a(1,y),d(1,y),[4]] Result=[1,b(2,x),d(1,x),a(1,y),d(1,y),[4]] Clock=4 Membrane=[1,b(2,x),a(1,x),d(2,x),[4]] Result=[1,b(2,x),a(1,x),d(2,x),[4]] 4. Conclusions This is the first version of the program. Let's call it ProMem, from Prolog for Membranes. The program is entirely presented in &3 and was ran on a Prolog dialect called LPA /6/ on any computer IMB-PC compatible. As any first version, it might have bugs. I will highly appreciate any comments concerning the program. In writing ProMem I followed the steps of the features of membrane computing and not programming shortcuts or tricks that might have give a better computation. The intention was to write a program so transparent that anyone who knows Prolog can understand how a super cell system works and any person familiar with the super cell system could read the Prolog program. It is possible that the effect is opposite. ProMem is devoted to develop applications of this new computational paradigm in order to evaluate the power and the opportunity to build actual machines. Bibliography 1. Gheorghe Paun, Computing with Membranes, Turku Centre for Computer Science, TUCS Technical report, N.208, November 1998. 2. Adrian Atanasiu, Parallel Computation in Super-Cell Systems, FCT ' 99, Iasi, Romania, 1999. 3. Jurgen Dassow, Gh. Paun, On the Power of Membrane Computing, FCT'99, Iasi, Romania, 1999. 4. Gheorghe,Paun, Grzegorz Rozenberg, Arto Salomaa, Membrane Computing with External Output, FCT'99, Iasi 1999. 5. Bratko Ivan, PROLOG, Programming for Artificial Intelligence, Addison-Wesley Pub. Comp, 1990. 6. Westwood Dave, LPA-Prolog 2.6 Technical reference, LPA Ltd, London England,1994.