Social Simulations (MiER v8:2, 1999)
The Prisoner's Dilemma
Louis J. D'Andria

Why are people generally honest in their dealings with others, even in the absense of a central authority to enforce good behavior? In this column, we model the role of ostracism as a tool for discouraging bad behavior, and thereby encouraging good behavior. We look at two cases in which people have the ability to remember or learn about other people's bad behavior. In the first situation, people remember every individual who has done them wrong in a previous encounter and they refuse to interact with such a person again. In the second situation, good guys use word-of-mouth or gossip in addition to personal experience to learn who are the bad guys, and they avoid interacting with a person with a bad rep even once.

The Prisoner's Dilemma

The most widely used theoretical model in the academic study of person-to-person interactions is known as the prisoner's dilemma. In this game-theoretic model, individuals interact with one another and as a result receive payoffs. This payoff, which can take all sorts of forms (monetary, psychological, etc.), is called a benefit if it is positive and a cost if it is negative.

The classical version of the prisoner's dilemma has two people who must interact and who do so without having information about each other. The payoffs to each person when they have the choice of being good or bad are shown in the following matrix.

({{ ,  , Good,  , Bad}, { ,  , R,  , T}, {Good, R,  , S,  }, { ,  , S,  , P}, {Bad, T,  , P,  }})

According to this payoff matrix, there are four possible outcomes of the interaction:

It has been shown analytically that for a single interaction between two people, it is always in each person's self-interest to be uncooperative if T > R > P > S.

In real life, relatively few person-to-person interactions satisfy the criteria of the classic prisoner's dilemma. In most cases, interactions are not mandatory and information about a person can be used to decide whether to interact with that person. Various sorts of information can be used for this purpose:

Fool Me Twice, Shame on Me

In this model, an individual decides whether to interact with another person, based on knowledge about that person which has been gained through a previous first-hand interaction with the person.

The System

Our model uses a square n by n lattice with wraparound boundary conditions. There is a population density p of individuals occupying lattice sites and the remaining sites are empty. A fraction g of the individuals are good guys and the rest of the people are bad guys. The system evolves over a given number of time steps t.

Populating Society

The value of an empty site is 0.

The value of a site occupied by an individual is a five-tuple, {a, b, c, d, e}, where the list elements are:

The initial system configuration consists of individuals randomly distributed on the lattice and facing randomly chosen directions. The individuals have names, zero resources, and no knowledge of the past behavior of other individuals. This configuration is created as follows.

k = 0;
RND := Random[Integer, {1, 4}]
society = Table[Floor[p + Random[]], {n}, {n}] /.
               1 :> {RND, ++k, Floor[g + Random[]], {}, 0}

Executing a Time Step

The following processes occur consecutively during each time step.

Note: Allowing an individual to check if he is on the other person's memory list is more efficient computationally than having each person keep a list of all of his previous interactions.

In either case, the individual refuses to interact; otherwise, the individual interacts with the other person and if the other person behaves badly, his name is added to the individual's bad guy list. In any cases, the individual receives a payoff. All other individuals remain unchanged.

Note: Since individuals that face each other during a given time step are unable to move during that time step, the two half-steps above, as well as the partial steps in the other programs in this chapter, could be combined into a single set of rules. However, they are kept separate here in order to make the explanation of the rules more transparent.

Interacting

The rules for interaction are as follows.

The first 4 rules apply to an individual who refuses to interact with a facing individual because in a previous interaction, one or the other or both of the individuals behaved badly. The cost associated with refusing to interact or opting out of an interaction is denoted W.

interact[{1, a1_, x1_, b1_, r_},
         {3, a3_, x3_, b3_, _}, _, _, _] :=
                {1, a1, x1, b1, r + W} /;
                     MemberQ[b1, a3] || MemberQ[b3, a1]
interact[{2, a2_, x2_, b2_, r_}, _,
         {4, a4_, x4_, b4_, _}, _, _] :=
                {2, a2, x2, b2, r + W} /;
                     MemberQ[b2, a4] || MemberQ[b4, a2]
interact[{3, a3_, x3_, b3_, r_}, _, _,
         {1, a1_, x1_, b1_, _}, _] :=
                {3, a3, x3, b3, r + W} /;
                     MemberQ[b3, a1] || MemberQ[b1, a3]
interact[{4, a4_, x4_, b4_, r_}, _, _, _,
         {2, a2_, x2_, b2_, _}] :=
                {4, a4, x4, b4, r + W} /;
                     MemberQ[b4, a2] || MemberQ[b2, a4]

The next 4 rules apply to a north-facing individual who interacts with a south-facing individual. There is a rule for each of the four possible combinations of good and bad behavior.

interact[{1, a1_, 1, b1_, r_},
         {3, a3_, 1, _, _}, _, _, _] :=
                                 {1, a1, 1, b1, r + R}
interact[{1, a1_, 0, b1_, r_},
         {3, a3_, 1, _, _}, _, _, _] :=
                                 {1, a1, 0, b1, r + T}
interact[{1, a1_, 1, b1_, r_},
         {3, a3_, 0, _, _}, _, _, _] :=
                    {1, a1, 1, Union[b1, {a3}], r + S}
interact[{1, a1_, 0, b1_, r_},
         {3, a3_, 0, _, _}, _, _, _] :=
                    {1, a1, 0, Union[b1, {a3}], r + P}

The 4 rules above can be written more compactly as a single rule that invokes a rule governing the payoff.  This rule relies on the fact that Drop with a second argument of 0 returns a list unchanged.

interact[{1, a1_, x1_, b1_, r_},
         {3, a3_, x3_, _, _}, _, _, _] :=
               {1, a1, x1, Union[b1, Drop[{a3}, x3]],
                                   r + payoff[x1, x3]}

There are similar rules for individuals facing in the other directions.

interact[{2, a2_, x2_ ,b2_, r_}, _,
         {4, a4_, x4_, _, _}, _, _] :=
               {2, a2, x2, Union[b2, Drop[{a4}, x4]],
                                   r + payoff[x2, x4]}
interact[{3, a3_, x3_, b3_, r_}, _, _,
         {1, a1_, x1_, _, _}, _] :=
               {3, a3, x3, Union[b3, Drop[{a1}, x1]],
                                   r + payoff[x3, x1]}
interact[{4, a4_, x4_, b4_, r_}, _, _, _,
         {2, a2_, x2_, _, _}] :=
               {4, a4, x4, Union[b4, Drop[{a2}, x2]],
                                   r + payoff[x4, x2]}

The payoff rules are given by

payoff[1, 1] = R
payoff[0, 1] = T
payoff[1, 0] = S
payoff[0, 0] = P

The last interact rule leaves empty sites and individuals who are not face-to-face with another person unchanged.

interact[z_, _, _, _, _] := z

The interact rules are applied to the lattice using the anonymous function

vonNeumann[interact, #]&

where

vonNeumann[func_, lat_] := 
  MapThread[func, Map[RotateRight[lat, #]&,
          {{0, 0}, {1, 0}, {0, -1}, {-1, 0}, {0, 1}}], 2]

Moving

The 28 rules for the movement of the individuals are developed in [Gaylord 1998], and are applied to the lattice sites using the anonymous function

GN[walk, vonNeumann[interact, #]]&

where

GN[func_, lat_] :=
  MapThread[func, Map[RotateRight[lat, #]&,
            {{0, 0}, {1, 0}, {0, -1}, {-1, 0}, {0, 1},
             {1, -1}, {-1, -1}, {-1, 1}, {1, 1}, {2, 0},
             {0, -2}, {-2, 0}, {0, 2}}], 2]

Evolving the System

The system evolves over t time steps, starting with the initial lattice configuration, society, using the following nesting operation.

NestList[vonNeumann[interact, GN[walk, #]]&, society, t]

See the end of this article for the assembled program: onceBurntTwiceShy.

Running the Simulation

We first run the onceBurntTwiceShy program on a 50 by 50 lattice having a 70% population density equally divided between good guys and bad guys over 500 time steps.  For the time being, we use symbolic payoffs.  This allows analysis of different sets of payoff values after a single simulation run.  We take advantage of this in the next model.

SeedRandom[21]
results = onceBurntTwiceShy[50, 0.7, 0.5, {P, R, S, T, W}, 500];

For the lattice configuration at a particular time step, the avgResourceLevel function computes the average of all the resource levels of individuals following a given strategy.

avgResourceLevel[lat_, strat_] := 
  (Apply[Plus, #]/Length[#])&[
                Cases[lat, {_, _, strat, _, x_} :> x, 2]];

The plotResources function uses the Graphics`MultipleListPlot` package to display the average resource level of good guys and bad guys over time.

Needs["Graphics`MultipleListPlot`"]

plotResources[lats_] := 
MultipleListPlot[
  Map[avgResourceLevel[#, 1]&, lats],
  Map[avgResourceLevel[#, 0]&, lats],
  SymbolShape -> None,
  PlotJoined -> True,
  PlotLegend -> {"Good guy", "Bad guy"},
  AxesLabel -> {"Time", "Resource level"},
  LegendShadow -> {-0.05, -0.05}];

In order to plot the resource levels, we must replace the symbolic payoffs with numeric payoffs.  We use Axelrod's values of {1, 3, 0, 5, 0}, which satisfy T > R > P > S.  The average resource levels for each type of individual over time is shown in the following.

plotResources[
        results  /.  
          Thread[{P, R, S, T, W} -> {1, 3, 0, 5, 0}]];

It appears that being able to remember past encounters with bad guys enables good to triumph over evil in terms of resource level but only in the long run. This is because the knowledge of bad behavior in the model is kept private—no one tells anyone else about it. We next see whether using public knowledge or gossip in addition to private knowledge can turn the tables on the bad guys even sooner.

I Heard It Through the Grapevine

We can allow individuals who interact with one another to share information or gossip about the bad behavior of other individuals. This exchange results in individuals being excluded or ostracized from interactions with people with whom they have never interacted in the past and so imposes an even higher penalty on past bad behavior than the previous model.

Interacting

The onceBurntTwiceShy program can be very easily modified to include gossiping by

interact[{1, a1_, x1_, b1_, r_},
         {3, a3_, x3_, b3_, _}, _, _, _] :=
               {1, a1, x1, Union[b1, b3, Drop[{a3}, x3]],
                                       r + payoff[x1, x3]}
interact[{2, a2_, x2_ ,b2_, r_}, _,
         {4, a4_, x4_, b4_, _}, _, _] :=
               {2, a2, x2, Union[b2, b4, Drop[{a4}, x4]],
                                       r + payoff[x2, x4]}
interact[{3, a3_, x3_, b3_, r_}, _, _,
         {1, a1_, x1_, b1_, _}, _] :=
               {3, a3, x3, Union[b3, b1, Drop[{a1}, x1]],
                                       r + payoff[x3, x1]}
interact[{4, a4_, x4_, b4_, r_}, _, _, _,
         {2, a2_, x2_, b2_, _}] :=
               {4, a4, x4, Union[b4, b2, Drop[{a2}, x2]],
                                       r + payoff[x4, x2]}

See the end of this article for the assembled program: badRep.

Running the Simulation

We run the program on a 50 by 50 lattice having a 70% population density equally divided between good guys and bad guys over 500 time steps, again using symbolic payoff values during the run.

SeedRandom[17]
results = badRep[50, 0.7, 0.5, {P, R, S, T, W}, 500];

The avgResourceLevel and plotResources functions used to analyse the onceBurntTwiceShy model can also be used here.  The following shows resource levels for two different sets of payoff values, both of which satisfy T > R > P > S.

plotResources[
        results  /.  
          Thread[{P, R, S, T, W} ->  {1, 3, 0, 5, 0}]];

plotResources[
        results  /.  
          Thread[{P, R, S, T, W} ->  {-1, 1, -2, 2, 
                0}]];

In both cases, the resource levels of the bad guys initially increase faster than the resource levels of the good guys. However, the fortunes of these two types of people reverse as time passes, with the good guys faring better in the long run.  Apparently, the bad guys initially gain at the expense of the good guys whom they are victimizing but as the word gets around - gossip spreads - the bad guys are ostracized from interacting with good guys, to their detriment.

References

Batali, John and Philip Kitcher. 1995. "Evolution of Altruism in Optional and Compulsory Games." Journal of Theoretical Biology 175: 161–171.
Enquist, Magnus and Olof Leimat. 1993. "The Evolution of Cooperation in Mobile Organisms." Animal Behavior 45: 747–757.
Frank, Robert H. 1988. Passions Within Reason: The Strategic Role of the Emotions. New York, NY: W.W. Norton.
Gaylord, Richard J. and Louis J. D'Andria. 1998. "Modeling a Society of Mobile Heterogeneous Individuals." Mathematica in Education and Research 7.3: 29–34.
Thaler, Richard H. 1992. The Winner's Curse: Paradoxes and Anomalies of Economic Life. The Free Press, chap. 2, 6–20. Reprinted from Robyn M. Dawes and Richard H. Thaler, 1988, "Cooperation." Journal of Economic Persepctives 2 (Summer): 187–197.

Programs

onceBurntTwiceShy[n_, p_, g_,
                         {P_, R_, S_, T_, W_}, t_] :=
Module[{RND, k = 0, society, interact, payoff,
                                   walk, vonNeumann, GN},
  RND := Random[Integer, {1, 4}];
  society = Table[Floor[p + Random[]], {n}, {n}] /.
               1 :> {RND, ++k, Floor[g + Random[]], {}, 0};
  payoff[1, 1] = R;
  payoff[0, 1] = T;
  payoff[1, 0] = S;
  payoff[0, 0] = P;
  interact[{1, a1_, x1_, b1_, r_},
           {3, a3_, x3_, b3_, _}, _, _, _] :=
                {1, a1, x1, b1, r + W} /;
                     MemberQ[b1, a3] || MemberQ[b3, a1];
  interact[{2, a2_, x2_, b2_, r_}, _,
           {4, a4_, x4_, b4_, _}, _, _] :=
                {2, a2, x2, b2, r + W} /;
                     MemberQ[b2, a4] || MemberQ[b4, a2];
  interact[{3, a3_, x3_, b3_, r_}, _, _,
           {1, a1_, x1_, b1_, _}, _] :=
                {3, a3, x3, b3, r + W} /;
                     MemberQ[b3, a1] || MemberQ[b1, a3];
  interact[{4, a4_, x4_, b4_, r_}, _, _, _,
           {2, a2_, x2_, b2_, _}] :=
                {4, a4, x4, b4, r + W} /;
                     MemberQ[b4, a2] || MemberQ[b2, a4];
  interact[{1, a1_, x1_, b1_, r_},
           {3, a3_, x3_, _, _}, _, _, _] :=
                {1, a1, x1, Union[b1, Drop[{a3}, x3]],
                                    r + payoff[x1, x3]};
  interact[{2, a2_, x2_ ,b2_, r_}, _,
           {4, a4_, x4_, _, _}, _, _] :=
                {2, a2, x2, Union[b2, Drop[{a4}, x4]],
                                    r + payoff[x2, x4]};
  interact[{3, a3_, x3_, b3_, r_}, _, _,
           {1, a1_, x1_, _, _}, _] :=
                {3, a3, x3, Union[b3, Drop[{a1}, x1]],
                                    r + payoff[x3, x1]};
  interact[{4, a4_, x4_, b4_, r_}, _, _, _,
           {2, a2_, x2_, _, _}] :=
                {4, a4, x4, Union[b4, Drop[{a2}, x2]],
                                    r + payoff[x4, x2]};
  interact[z_, _, _, _, _] := z;
  walk[{1,a___},0,_,_,_,{4,___},_,_,_,_,_,_,_] := {RND,a};
  walk[{1,a___},0,_,_,_,_,_,_,{2,___},_,_,_,_] := {RND,a};
  walk[{1,a___},0,_,_,_,_,_,_,_,{3,___},_,_,_] := {RND,a};
  walk[{1,a___},0,_,_,_,_,_,_,_,_,_,_,_] := 0;
  walk[{2,a___},_,0,_,_,{3,___},_,_,_,_,_,_,_] := {RND,a};
  walk[{2,a___},_,0,_,_,_,{1,___},_,_,_,_,_,_] := {RND,a};
  walk[{2,a___},_,0,_,_,_,_,_,_,_,{4,___},_,_] := {RND,a};
  walk[{2,a___},_,0,_,_,_,_,_,_,_,_,_,_] := 0;
  walk[{3,a___},_,_,0,_,_,{4,___},_,_,_,_,_,_] := {RND,a};
  walk[{3,a___},_,_,0,_,_,_,{2,___},_,_,_,_,_] := {RND,a};
  walk[{3,a___},_,_,0,_,_,_,_,_,_,_,{1,___},_] := {RND,a};
  walk[{3,a___},_,_,0,_,_,_,_,_,_,_,_,_] := 0;
  walk[{4,a___},_,_,_,0,_,_,{1,___},_,_,_,_,_] := {RND,a};
  walk[{4,a___},_,_,_,0,_,_,_,{3,___},_,_,_,_] := {RND,a};
  walk[{4,a___},_,_,_,0,_,_,_,_,_,_,_,{2,___}] := {RND,a};
  walk[{4,a___},_,_,_,0,_,_,_,_,_,_,_,_] := 0;
  walk[{_,a___},_,_,_,_,_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,{3,___},{4,___},_,_,_,_,_,_,_,_,_,_] := 0;
  walk[0,{3,___},_,{1,___},_,_,_,_,_,_,_,_,_] := 0;
  walk[0,{3,___},_,_,{2,___},_,_,_,_,_,_,_,_] := 0;
  walk[0,_,{4,___},{1,___},_,_,_,_,_,_,_,_,_] := 0;
  walk[0,_,{4,___},_,{2,___},_,_,_,_,_,_,_,_] := 0;
  walk[0,_,_,{1,___},{2,___},_,_,_,_,_,_,_,_] := 0;
  walk[0,{3,a___},_,_,_,_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,_,{4,a___},_,_,_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,_,_,{1,a___},_,_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,_,_,_,{2,a___},_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,_,_,_,_,_,_,_,_,_,_,_,_] := 0;
  vonNeumann[func_, lat_] := 
    MapThread[func, Map[RotateRight[lat, #]&,
          {{0, 0}, {1, 0}, {0, -1}, {-1, 0}, {0, 1}}], 2];
 GN[func_, lat_] :=
    MapThread[func, Map[RotateRight[lat, #]&,
            {{0, 0}, {1, 0}, {0, -1}, {-1, 0}, {0, 1},
             {1, -1}, {-1, -1}, {-1, 1}, {1, 1}, {2, 0},
             {0, -2}, {-2, 0}, {0, 2}}], 2];
  NestList[vonNeumann[interact, GN[walk, #]]&, society, t]]

badRep[n_, p_, g_, {P_, R_, S_, T_, W_}, t_] := 
Module[{RND, k = 0, society, interact, payoff,
                                   walk, vonNeumann, GN},
  RND := Random[Integer, {1, 4}];
  society = Table[Floor[p + Random[]], {n}, {n}] /.
               1 :> {RND, ++k, Floor[g + Random[]], {}, 0};
  payoff[1, 1] = R;
  payoff[0, 1] = T;
  payoff[1, 0] = S;
  payoff[0, 0] = P;
  interact[{1, a1_, x1_, b1_, r_},
           {3, a3_, x3_, b3_, _}, _, _, _] :=
                {1, a1, x1, b1, r + W} /;
                     MemberQ[b1, a3] || MemberQ[b3, a1];
  interact[{2, a2_, x2_, b2_, r_}, _,
           {4, a4_, x4_, b4_, _}, _, _] :=
                {2, a2, x2, b2, r + W} /;
                     MemberQ[b2, a4] || MemberQ[b4, a2];
  interact[{3, a3_, x3_, b3_, r_}, _, _,
           {1, a1_, x1_, b1_, _}, _] :=
                {3, a3, x3, b3, r + W} /;
                     MemberQ[b3, a1] || MemberQ[b1, a3];
  interact[{4, a4_, x4_, b4_, r_}, _, _, _,
           {2, a2_, x2_, b2_, _}] :=
                {4, a4, x4, b4, r + W} /;
                     MemberQ[b4, a2] || MemberQ[b2, a4];
  interact[{1, a1_, x1_, b1_, r_},
           {3, a3_, x3_, b3_, _}, _, _, _] :=
               {1, a1, x1, Union[b1, b3, Drop[{a3}, x3]],
                                      r + payoff[x1, x3]};
  interact[{2, a2_, x2_ ,b2_, r_}, _,
           {4, a4_, x4_, b4_, _}, _, _] :=
               {2, a2, x2, Union[b2, b4, Drop[{a4}, x4]],
                                      r + payoff[x2, x4]};
  interact[{3, a3_, x3_, b3_, r_}, _, _,
           {1, a1_, x1_, b1_, _}, _] :=
               {3, a3, x3, Union[b3, b1, Drop[{a1}, x1]],
                                      r + payoff[x3, x1]};
  interact[{4, a4_, x4_, b4_, r_}, _, _, _,
           {2, a2_, x2_, b2_, _}] :=
               {4, a4, x4, Union[b4, b2, Drop[{a2}, x2]],
                                      r + payoff[x4, x2]};
  interact[z_, _, _, _, _] := z;
  walk[{1,a___},0,_,_,_,{4,___},_,_,_,_,_,_,_] := {RND,a};
  walk[{1,a___},0,_,_,_,_,_,_,{2,___},_,_,_,_] := {RND,a};
  walk[{1,a___},0,_,_,_,_,_,_,_,{3,___},_,_,_] := {RND,a};
  walk[{1,a___},0,_,_,_,_,_,_,_,_,_,_,_] := 0;
  walk[{2,a___},_,0,_,_,{3,___},_,_,_,_,_,_,_] := {RND,a};
  walk[{2,a___},_,0,_,_,_,{1,___},_,_,_,_,_,_] := {RND,a};
  walk[{2,a___},_,0,_,_,_,_,_,_,_,{4,___},_,_] := {RND,a};
  walk[{2,a___},_,0,_,_,_,_,_,_,_,_,_,_] := 0;
  walk[{3,a___},_,_,0,_,_,{4,___},_,_,_,_,_,_] := {RND,a};
  walk[{3,a___},_,_,0,_,_,_,{2,___},_,_,_,_,_] := {RND,a};
  walk[{3,a___},_,_,0,_,_,_,_,_,_,_,{1,___},_] := {RND,a};
  walk[{3,a___},_,_,0,_,_,_,_,_,_,_,_,_] := 0;
  walk[{4,a___},_,_,_,0,_,_,{1,___},_,_,_,_,_] := {RND,a};
  walk[{4,a___},_,_,_,0,_,_,_,{3,___},_,_,_,_] := {RND,a};
  walk[{4,a___},_,_,_,0,_,_,_,_,_,_,_,{2,___}] := {RND,a};
  walk[{4,a___},_,_,_,0,_,_,_,_,_,_,_,_] := 0;
  walk[{_,a___},_,_,_,_,_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,{3,___},{4,___},_,_,_,_,_,_,_,_,_,_] := 0;
  walk[0,{3,___},_,{1,___},_,_,_,_,_,_,_,_,_] := 0;
  walk[0,{3,___},_,_,{2,___},_,_,_,_,_,_,_,_] := 0;
  walk[0,_,{4,___},{1,___},_,_,_,_,_,_,_,_,_] := 0;
  walk[0,_,{4,___},_,{2,___},_,_,_,_,_,_,_,_] := 0;
  walk[0,_,_,{1,___},{2,___},_,_,_,_,_,_,_,_] := 0;
  walk[0,{3,a___},_,_,_,_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,_,{4,a___},_,_,_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,_,_,{1,a___},_,_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,_,_,_,{2,a___},_,_,_,_,_,_,_,_] := {RND,a};
  walk[0,_,_,_,_,_,_,_,_,_,_,_,_] := 0;
  vonNeumann[func_, lat_] := 
    MapThread[func, Map[RotateRight[lat, #]&,
          {{0, 0}, {1, 0}, {0, -1}, {-1, 0}, {0, 1}}], 2];
  GN[func_, lat_] :=
    MapThread[func, Map[RotateRight[lat, #]&,
            {{0, 0}, {1, 0}, {0, -1}, {-1, 0}, {0, 1},
             {1, -1}, {-1, -1}, {-1, 1}, {1, 1}, {2, 0},
             {0, -2}, {-2, 0}, {0, 2}}], 2];
  NestList[vonNeumann[interact, GN[walk, #]]&, society, t]]