import "Std/List" type Event = (rec E = [ publish=/[E Sig] print=/[Sig] getPublisher=/[/String] getSpace = /[/String] getContent = /[/String] ]) type Agent = (rec A = [ toString=/[/String] sendFriendReq=/[A A Sig] friendReq=/[A A Sig] removeFriend=/[A A Sig] publishMyEvent=/[A String Sig] publishEvent=/[A String A Sig] sendEvent=/[Event Sig] receiveEvent=/[Event Sig] printSpace=/[Sig] ]) {- Utility function to check for list membership -} def contains (#X l:(List X) x:X f:/[X X /Bool]) : Bool = (not (null (list.filter l \(y:X):Bool = (f x y)))) {- Utility function to remove element from list -} def remove (#X l:(List X) x:X f:/[X X /Bool]) : (List X) = (list.filter l \(y:X):Bool = (not (f x y))) def eqAgent (a1:Agent a2:Agent):Bool = (val (rec aa1) = a1 val (rec aa2) = a2 (==$ (aa1.toString) (aa2.toString))) def eqEvent (e1:Event e2:Event): Bool = (val (rec ee1) = e1 val (rec ee2) = e2 (&& > (==$ (ee1.getPublisher) (ee2.getPublisher)) (==$ (ee1.getSpace) (ee2.getSpace)) (==$ (ee1.getContent) (ee2.getContent)))) {- - Event implementation in Pict -} def event (p:Agent s:Agent c:String) : Event = (new publisher:^Agent run publisher!p new space:^Agent run space!s new content:^String run content!c (rec [ publish = \[self:Event c:Sig] = (new c1:^[] new c2:^[] new c3:^[] (space?s = (space!s | (val (rec ss) = s (ss.receiveEvent![self (rchan c1)] | ss.sendEvent![self (rchan c2)] | publisher?p = (publisher!p | if (not (eqAgent s p)) then (val (rec pp) = p pp.sendEvent![self (rchan c3)]) else c3![] )))) | c1?[] = c2?[] = c3?[] = (c![] | content?x = (content!x | ((prNL (+$ x " published!")); ()))))) print = \[c:Sig] = publisher?p = space?s = content?x = (publisher!p | space!s | content!x | (val (rec pp) = p val (rec ss) = s prNL![(+$ > (pp.toString) " wrote in " (ss.toString) "'s space: " x) c] )) getPublisher = \[res:!String] = publisher?p = ( publisher!p | (val (rec pp) = p res!(pp.toString)) ) getSpace = \[res:!String] = space?s = ( space!s | (val (rec ss) = s res!(ss.toString)) ) getContent = \[res:!String] = content?x = (content!x | res!x) ])) {- - Agent implementation in Pict -} def agent (n:String) : Agent = (new name:^String run name!n new friends:^(List Agent) run friends!nil new wannaBe:^(List Agent) run wannaBe!nil new space:^(List Event) run space!nil (rec [ toString = \[res:!String] = name?n = ( res!n | name!n ) sendFriendReq = \[self:Agent a:Agent c:Sig] = (val (rec aa) = a friends?f = (friends!f | if (contains #Agent f a eqAgent) then ((prNL (+$ "Already friends with: " (aa.toString))) ; ()) else (((prNL "Sending friend request..."); ()) | wannaBe?w = (wannaBe!(cons a w) | ((aa.friendReq a self); ()) ) ) | c![] )) friendReq = \[self:Agent a:Agent c:Sig] = (((prNL "Received friend request..."); ()) | (val (rec aa) = a friends?f = if (contains #Agent f a eqAgent) then (friends!f | ((prNL (+$ "Already friends with: " (aa.toString))) ; ())) else wannaBe?w = if (contains #Agent w a eqAgent) then (wannaBe!(remove #Agent w a eqAgent) | friends!(cons a f) | ((aa.friendReq a self); ()) ) else () ) | c![] ) removeFriend = \[self:Agent a:Agent c:Sig] = (((prNL "Removing friend..."); ()) | (val (rec aa) = a friends?f = if (not (contains #Agent f a eqAgent)) then (friends!f | ((prNL (+$ "Not friends with: " (aa.toString))) ; ())) else (friends!(remove #Agent f a eqAgent) | ((aa.removeFriend a self); ()) ) ) | c![] ) publishMyEvent = \[self:Agent s:String c:Sig] = (val e = (event self self s) val (rec ee) = e ee.publish![e c]) publishEvent = \[self:Agent s:String a:Agent c:Sig] = (val (rec aa) = a friends?f = (friends!f | if (not (contains #Agent f a eqAgent)) then (((prNL (+$ "Not friends with: " (aa.toString))); ()) | c![]) else (val e = (event self a s) val (rec ee) = e ee.publish![e c]) )) sendEvent = \[e:Event c:Sig] = friends?f = ( friends!f | list.apply![#Agent f \(a:Agent):[] = (val (rec aa) = a (aa.receiveEvent e)) c] ) receiveEvent = \[e:Event c:Sig] = (space?s = if (not (contains #Event s e eqEvent)) then space!(cons e s) else space!s | c![] ) printSpace = \[c:Sig] = space?s = name?n = (space!s | name!n | ((prNL (+$ > "*** " n "'s Events***")); (list.apply s \(e:Event):[] = (val (rec ee) = e (ee.print))); prNL![(+$ > "*** " n "'s events finished.***") c]) ) ])) {- - Social network implementation in Pict -} val a = (agent "a") val b = (agent "b") val c = (agent "c") val d = (agent "d") val e = (agent "e") val f = (agent "f") val (rec aa) = a val (rec bb) = b val (rec cc) = c val (rec dd) = d val (rec ee) = e val (rec ff) = f run ((aa.sendFriendReq a b); (bb.sendFriendReq b a); (aa.sendFriendReq a c); (cc.sendFriendReq c a); (cc.sendFriendReq c b); (bb.sendFriendReq b c); (aa.sendFriendReq a e); (ee.sendFriendReq e a); (cc.sendFriendReq c d); (dd.sendFriendReq d c); (ff.sendFriendReq f d); (dd.sendFriendReq d f); (aa.publishMyEvent a "a_e1"); (ff.publishMyEvent f "f_e1"); (cc.publishMyEvent c "c_e1"); (cc.publishEvent c "c_e2" a); (cc.publishEvent c "c_e3" d); (aa.printSpace); (bb.printSpace); (cc.printSpace); (dd.printSpace); (ee.printSpace); (ff.printSpace); () )