Constructing and manipulating games

The whole point of the GCL is to provide an environment to enable building and doing computations on games. This chapter describes how to build and solve normal and extensive form games in the GCL.

Normal form games

A normal form game is a set of players, each with a strategy set, together with a function from the cartesian product of strategy sets to a set of outcomes. Each outcome results in a payoff to each of the players. To construct a normal form game, one must therefore define each of these parts. A collection of GCL functions is available for building and editing normal form games. A complete list is given in the sections on ``Normal Form Manipulation'' in the Categorical Function Reference section of the manual. The most generally-useful functions are given in the table.

Table 7. Overview of normal form manipulation functions

FunctionDescription
DeleteOutcome[o]Deletes outcome \verb+o+ from its game
NewOutcome[n]Returns a new outcome for the game
NewOutcome[n,name] (user-defined)Returns a new outcome named name for game n
NewOutcome[p] (user-defined)Attaches a new outcome with zero payoffs to the pure profile p
Outcome[p]The outcome attached to the pure strategy profile p
OutcomeForm[n]The game form for game n
Outcomes[n]List of outcomes defined for game n
SetOutcome[p,o]Attach outcome o to pure strategy profile p
NewNfg[dim]A new normal form with dimensions dim
NewNfg[dim,True] (user-defined)A new normal form with dimensions dim, outcomes in all cells
Nfg[e]Converts extensive form game e to normal form
Nfg[x] (user-defined)Converts nested list of numbers x to normal form
Payoff[o,pl]Payoff of outcome o to player pl
Payoff[m,pl]Payoff of mixed profile m to player pl
Payoffs[p] (user-defined)Payoffs of pure strategy p
Payoffs[n] (user-defined)Normal form game payoffs of n as a nested list
Payoffs[o] (user-defined)Payoffs of outcome o
Payoffs[m] (user-defined)Payoffs of mixed profile m
Randomize[n,j] (user-defined)Randomizes the payoffs in n with seed j
Strategies[pl] (user-defined)Strategies for player pl
Strategies[n] (user-defined)Strategies for game n
SetPayoff[o,pl,pay]Set payoff to player pl in outcome o to pay

Creating a normal form game

The function NewNfg is used to create a new normal form game. Thus, the expression

GCL1:= NewNfg[{2,3,2}]
will create a new normal form game with three players, where the first player has two strategies, the second player has three strategies, and the third player has two strategies. Since no outcomes have been defined, all strategy tuples of pure strategies result in the null outcome, which has payoff of zero for all players.

The game created by NewNfg is not very interesting, because all payoffs for all strategies are zero. To make it more interesting, outcomes must be created and associated with strategy tuples. To create a separate outcome for each pure strategy, one can specify the second argument in NewNfg to be True. These outcomes will still have zero payoffs until they are changed. The function Randomize can be used to randomize the payoffs of each outcome in the game. In this way, NewNfg can be used to create more interesting games by using it as an argument to other functions that accept normal form games as arguments.

For example, to create a random two person 2 by 2 normal form game, with a seed of 34 for the random number generator, you can use the function Randomize to randomize the payoffs of the original game:

GCL2:= Randomize[NewNfg[{2,2},True],34]
You can look at the payoffs of the game by using the user-defined function from stdudfs.gcl, Payoffs (using Float to convert the payoffs of the game to floating point precision first):
GCL3:= << Payoffs[Float[Randomize[NewNfg[{2,2},True],34]]]
{ { { 0.159964, 0.026784 }, { 0.421515, 0.399322 } },
  { { 0.233245, 0.923402 }, { 0.039071, 0.695271 } } }
Here, the payoffs are written in a nested list, where the \verb+(i,j)+th component is the vector of payoffs when player 1 takes strategy i and player 2 takes strategy j. The game can be solved for all mixed Nash equilibria by
GCL4:= << AllNash[Randomize[NewNfg[{2,2},True],34]]
{ (Mixed) { 1.000000 0.000000 }{ 0.000000 1.000000 },
  (Mixed) { 0.000000 1.000000 }{ 1.000000 0.000000 },
  (Mixed) { 0.379795 0.620205 }{ 0.839199 0.160801 } }

In all of the above examples, all work is thrown out, and the normal form game is created anew in each successive command. You can avoid such wasteful computation, and minimize the typing you need to do by saving intermediate results in a variable. For example, the above could be done as follows:

GCL1:= n:=Randomize[NewNfg[{2,2},True],34];
GCL2:= p:=Payoffs[n];
GCL3:= m:=EnumMixedSolve[n];

The first statement creates a variable n to store the normal form game. This variable is then used as an argument in the next two function calls. The second two statements create variables p and m to store the nested list of payoffs of the game, and the list of mixed strategy solutions of the game. Any of these variables can then be used as input to other function calls, as long as the data type of the variable is the same as the data type of the

The above also illustrates another important principle of the GCL. All of the functions in the GCL (with a few exeptions, noted in the Function Reference Section) return objects of some specific data type. Any object returned by a function can be stored in a variable. While the GCL supports a large number specialized data types, the data typing is all implicit. In other words, you never have to declare what data type a variable will be before it is used. A variable takes on the data type of the object that is first assigned to it.

Setting payoffs

The payoffs in a normal form can be set to have specific values using the SetPayoff function. The following sequence of expressions illustrates how to build a simple prisoner's dilemma game, by first creating a normal form game with the appropriate number of players and strategies, and then modifying the payoffs one by one.

GCL1:= n:=NewNfg[{2,2}]
GCL2:= s:=Strategies[n]
GCL3:= NewOutcome[{s_1_1,s_2_1},{9.0,9.0}]
GCL4:= NewOutcome[{s_1_1,s_2_2},{0.0,10.0}]
GCL5:= NewOutcome[{s_1_2,s_2_1},{10.0,0.0}]
GCL6:= NewOutcome[{s_1_2,s_2_2},{1.0,1.0}]
GCL7:= << Payoffs[n]
{ { { 9.000000, 9.000000 }, { 0.000000, 10.000000 } },
  { { 10.000000, 0.000000 }, { 1.000000, 1.000000 } } }
Note that the above can be done equivalently and more simply by using the standard user-defined function, Nfg, to create the game directly from a payoff list:
GCL1:= n:=Nfg[{{{9,9},{0,10}},{{10,0},{1,1}}}]
GCL2:= << Payoffs[n]
{ { { 9.000000, 9.000000 }, { 0.000000, 10.000000 } },
  { { 10.000000, 0.000000 }, { 1.000000, 1.000000 } } }
You can name the strategies if you want by using Strategies to get a list of the strategies in the game, and SetName to name them.
GCL3:= s:=Strategies[n]
GCL4:= SetName[s_1,{"Cooperate","Defect"}]
GCL5:= SetName[s_2,{"Cooperate","Defect"}]
GGCL6:= << Name[s]
{ { Cooperate, Defect },
  { Cooperate, Defect } }

We now give a more complicated example, in which one can use listability of vector and matrix operations to set the payoffs in the normal form according to a formula. In this example, we create a version of the ``stag hunt'' game.

GCL1:= << strat:=List[1,3,1]
{ 1, 2, 3 }
GCL2:= << stratSets:=List[strat,2]
{ { 1, 2, 3 },
  { 1, 2, 3 } }
GCL3:= << effort:=CartesianProd[stratSets] 
{ { { 1, 1 }, { 1, 2 }, { 1, 3 } },
  { { 2, 1 }, { 2, 2 }, { 2, 3 } },
  { { 3, 1 }, { 3, 2 }, { 3, 3 } } }
GCL4:= << pay:=Min[effort]-.5*effort
{ { { 0.500, 0.500 }, { 0.500, 0.000 }, { 0.500, -0.500 } },
  { { 0.000, 0.500 }, { 1.000, 1.000 }, { 1.000, 0.500 } },
  { { -0.500, 0.500 }, { 0.500, 1.000 }, { 1.500, 1.500 } } }
GCL5:= << n:=Nfg[pay]
(Nfg) ""

First, the set of effort levels for a player (consisting of the list of integers from one to 3) is constructed and stored in the variable strat. (While this variable is called strat, its data type is LIST(INTEGER), not STRATEGY.) Second, the set of strategy sets for both players is assembled in stratSets. Third, the set of pure strategy profiles is assembled by taking the cartesian product of the strategy sets, and converted to NUMBER to give a vector of efforts for each pure strategy profile. The result is stored in the variable effort. Fourth, the vector of payoffs for each pure strategy profile is computed by taking, for vector of payoffs, the minimum effort across players, and subtracting the cost of effort for each player. Finally, a game is constructed with these payoffs, by using the function Nfg. If you now ask to see the payoffs for the game via Payoffs[nfg], you will see an array just like pay.

The fourth step in the above calculation illustrates a subtle but important point about listable functions. The function Min requires an argument of type LIST(NUMBER) and returns type NUMBER. It is being called with an argument of type LIST(LIST(LIST(NUMBER))), with dimension 3 by 3 by 2. Hence, the function will be run as a listable function on the innermost vectors in the nested list, generating a result of type LIST(LIST(NUMBER)), with dimension 3 by 3, each entry of which contains the minimum of the vector in that cell. Thus:

GCL6:= << Min[effort]
{ { 1, 1, 1 },
  { 1, 2, 2 },
  { 1, 2, 3 } }
To subtract the component .5*effort from this, the function Minus requires data of type NUMBER for both arguments. It is being run with the first argument of type LIST(LIST(NUMBER)) with dimension 3 by 3, and the second of type LIST(LIST(LIST(NUMBER))), with dimension 3 by 3 by 2. The first two levels of the list for both arguments match in dimension. Then it encounters a NUMBER in the first argument, and a LIST(NUMBER) of dimension 2 on the second. Hence, Minus runs listably on its second argument, yielding a LIST(NUMBER) of dimension 2 for each entry in the 3 by 3 nested list of Min[effort].

The functions used in the above construction will accept nested lists of any level. Hence, the above can be extended into a user defined function which allows one to build a stag hunt game for an arbitrary number of players and strategies:

NewFunction[StagHuntNfg[n->INTEGER,maxeff->INTEGER,cost->NUMBER]=:NFG,
  strats:=List[1,maxeff,1];
  effort:=CartesianProd[List[strats,n]];
  Nfg[Min[effort]-cost*effort];
];
The expressions in this user defined function are analagous to the steps in the two person example above. Once the above function has been defined, then you can then use it as follows:
n:=StagHuntNfg[4,2,.5];
to create a four person stag hunt game where each player has two strategy choices (effort levels) and the cost of effort is .5.

Once a normal form game has been defined, there are a number of solution algorithms that can be applied to solve the game. How to solve normal form games is discussed in the next chapter. Until you get to that point, you might want to save your work.

Saving and loading normal form games

Once a normal form game has been constructed, it can be saved in a similar way to an extensive form game. The expression

SaveNfg[n, "filename.nfg"]
will save the normal form game n to the file filename.nfg. It is recommended that the filename extension .nfg be used when saving normal form games, as the Gambit graphical user interface recognizes this extension as containing normal form games. Once a normal form game has been saved to an external file, it can be loaded by the command LoadNfg, as follows:
n := LoadNfg["filename.nfg"]

Extensive forms

Creating a new extensive form

The function NewEfg can be used to create a new extensive form game. In order to do anything with it, a variable should be created to be the new extensive form game. Thus, the expression

e := NewEfg[]
will create a new extensive form game stored in e. The game is a trivial game with only one node, the root node, and no players (besides the chance player used to represent the realizations of random events). You can create a game which has two players, named Fred and Alice, by specifying
e := NewEfg[{"Fred", "Alice"} ]

For an arbitrary extensive form game, a number of functions are available to get information about the game. A complete list is given in the section on ``Getting Information'' in the Categorical Function Reference section of this manual. Some of the more important functions are given in the table.

Table 8. Overview of functions on extensive forms

FunctionDescription
Actions[i] (user-defined)Actions at information set i
Actions[e] (user-defined)Actions in the game e
Chance[e]Chance player of e
Children[n]Child nodes of node n
History[n] (user-defined)History of actions preceeding node n
Infoset[n]Information set that node n belongs to
Infoset[a]Information set that action a belongs to
Infosets[e]Information sets in the game e
Members[i]Member nodes of information set i
Nodes[e]Nodes in the game tree of the game e
NonterminalNodes[e] (user-defined)Nonterminal nodes of game e
NthChild[n,j]The jth child of node n
Outcome[n]Outcome attached to node n
Outcomes[e]Outcomes for the game e
Parent[n]Parent node of node n
Payoff[o,p]Payoff of outcome o for player p
Payoffs[o] (user-defined)Payoff vector of outcome o
Payoffs[b] (user-defined)Payoff vector of profile b
Player[i]Player of information set i
Players[e]Players of the game e
PriorAction[n]Action preceding node n
RootNode[e]Root node of e
TerminalNodes[e] (user-defined)Terminal nodes of game e

The NthChild function has a short form of n#j. So, the second child of the third child of the root node of an extensive form game e can be obtained (if it exists) by the expression RootNode[e]#3#2.

Modifying an extensive form

A series of extensive form game editing functions are available for modifying an extensive form game. A complete list is given in the section on ``Extensive form manipulation'' in the Categorical Function Reference section of this manual. The more important functions for building a game are given in the table.

Table 9. Functions for modifying extensive form games

FunctionDescription
AddMove[i,n]Adds a move from infoset i to node n
AddMove[i,a] (user-defined)Adds a move from infoset i to action a
CopyTree[n1,n2]Copies tree rooted at node n1 to node n2
InsertAction[i]Inserts an action into information set i
InsertMove[i,n]Inserts a move from infoset i at node n
MergeInfosets[i1,i2]Moves nodes from infoset i2 into i1
MoveToInfoset[n,i]Moves node n into infoset i
NewInfoset[p,j]Creates a new infoset for player p with j actions
NewInfoset[p,list] (user-defined)Creates a new infoset for p with action names as in \list
NewOutcome[e,t] (user-defined)Creates a new outcome for the game e with name t
NewPlayer[e,t] (user-defined)Creates a new player for the game e with name t
Randomize[e,j] (user-defined)Randomizes the payoffs in e with seed j
Reveal[i,list]Reveals infoset i to players in list
SetChanceProbs[i,list]Sets chance probs in infoset i to values in list
SetOutcome[n,o]Attaches outcome o to node n
SetPayoff[o,p,v]Sets payoff of outcome o for player p to value v
SetPayoffs[o,list] (user-defined)Sets payoff of outcome o to values in list
The functions in the table can be used to build up any valid extensive form game from a trivial game. The basic procedure by which a more complex game is constructed from a simple game is:

  1. Create a new game, and create all players.

  2. Iteratively add moves to the game. This involves two steps

    1. Construct a ``template'' for a move by creating an information set for a player with the desired choices (actions).

    2. Add the move to the game for the appropriate histories of actions.

  3. Reveal information about the moves to players that observe them.

  4. Compute payoffs and attach outcomes to the game.

The next to last step (revealing information) may require considerable care for games with complex information structures. It is usually easiest to wait to do this step until the entire game tree is built, since Gambit does not maintain a game of perfect recall as you add new moves. Hence, if you reveal a move of player 1 to player 2, and then add new moves to the game for the player 2, the move that was revealed to player 2 will not be ``remembered'' by player 2 at the new moves.

The following sequence of commands builds the game tree for a simple poker game as described in [Mye91], as outlined below.

                         Game Description:

Fred (Player 1) and Alice (Player 2) each ante $1.00 into the pot.
Fred draws a card from a deck; Fred observes the card; Alice does not. 
Fred moves:
  If Fred Folds, 
    Fred wins the pot if his card is Red (net gain of $1.00 to Fred).
    Fred loses the pot if his card is Black (net loss of $1.00 to Fred).
  If Fred Raises, then Fred throws a dollar in the pot, and Alice moves:
    If Alice Passes, then Fred wins the pot (net gain of $1.00 to Fred)
    If Alice Meets, she throws a dollar in the pot; Fred must show the card: 
      If the card is Red Fred wins the pot (net gain of $2.00 to Fred).
      If the card is Black Alice wins the pot (net loss of $2.00 to Fred)

To construct this game, first we create a new game, and the players. We create the players separately, using NewPlayer so that we have variables to refer to them later:

e := NewEfg[];
fred := NewPlayer[ e, "Fred"];
alice := NewPlayer[e,"Alice"];

Now, we iteratively add moves to the game, by creating an information set with a template for the move, and then adding that move to the game at the appropriate histories:

deal := NewInfoset[ Chance[e], {"Red", "Black"}];
AddMove[deal,RootNode[e]];
fredmove := NewInfoset[ fred , {"Raise", "Fold"} ];
AddMove[ fredmove, TerminalNodes[e]];
alicemove := NewInfoset[ alice , {"Meet", "Pass"} ];
fredraised:=Filter[t:=TerminalNodes[e],Name[PriorAction[t]]="Raise"]
AddMove[alicemove,fredraised];
In the above, the first move, deal, is a chance move. It is added at the root node of the game. The second move is called fredmove, and is added at the terminal nodes of the tree, since Fred gets to take this move for any draw of the card. Since there are two terminal nodes the call to AddMove here is a listable call, and adds the move to both terminal nodes of the tree. The third move is called alicemove. Alice only gets to move if Fred chooses to raise. So the step computing fredraised identifies all of the terminal nodes whose prior action was named "Raise". The move alicemove is added at all of these nodes, via a listable call to AddMove. At this point, if you execute the expression
Display[e]
you can launch the graphical interview to view the game in its current state. You will see that the game tree looks like the game in [Mye91], except there are no payoffs yet, and Fred only has one information set. This is because you did not yet account for the fact that the deal is revealed to Fred. You can reveal the deal to Fred (but not to Alice) via
Reveal[deal,{fred}];
and if you now display the game, then except for the fact that no payoffs have yet been defined, the game tree should look like that in [Mye91]. Note that an alternate way to get the information structure correct is to create separate information sets for Fred's moves from the outset. So, the expressions
fredmove := NewInfoset[fred , {"Raise", "Fold"}];
AddMove[fredmove, TerminalNodes[e]];
in the above example could be replaced with
fredred := NewInfoset[fred , {"Raise", "Fold"}];
fredblack := NewInfoset[fred , {"Raise", "Fold"}];
AddMove[ fredred, RootNode[e]#1];
AddMove[ fredblack, RootNode[e]#2];
(Here, the short form n#j for NthChild is used to refer to the jth child of node n). A move from the information set fredred is added to the first child of the root node (which is the action for chance in which the red card is selected) and a move from the second information set fredblack is added to the second child of the root node. Now, since two separate information sets for Fred are created from the outset, there is no need to reveal the deal to Fred. As with life in general, in the GCL there is usually more than one way to skin a cat.

To complete construction of this game, we must now add payoffs. This can be done with the following sequence of expressions

ante := 1.00;
raise := 1.00;
win := SetPayoffs[NewOutcome[e, "Win"],{ante,-ante}];
winbig := SetPayoffs[NewOutcome[e, "Win Big"],{ante+raise,-ante-raise}];
lose := SetPayoffs[NewOutcome[e, "Lose"],{-ante,ante}];
losebig := SetPayoffs[NewOutcome[e, "Lose Big"],{-ante-raise,ante+raise}];
SetOutcome[TerminalNodes[e],{winbig,win,win,losebig,win,lose}]

This example has shown how to construct a simple game without any recursive structure. This game might be just as easily created in the graphical interface. The usefulness of the GCL in constructing games comes when the game is larger, or has some repetitive structure to it. In Appendix A, part 1, we give an example showing how to construct a multi stage holdout game using user defined functions.

Saving and loading extensive forms

Once an extensive form game has been constructed, it can be saved by the expression

SaveEfg[e, "filename.efg"]
where e is the extensive form game, and filename.efg is the filename of the file to be created. It is recommended that the filename extension .efg be used when saving extensive form games, as the Gambit graphical user interface recognizes this extension as containing extensive form games. Once an extensive form game has been saved to an external file, it can be loaded by the function LoadEfg, as follows:
e := LoadEfg["filename.efg"]

Creating a normal form from an extensive form

A normal form game can also be created from an extensive form game. If e is an extensive form game, then the expression

n := Nfg[e]
will create a normal form game n which is the reduced normal form game associated with the extensive form game e.

Strategies in the reduced normal form are given default names consisting of a series of digits, where the jth digit in the strategy name corresponds to the branch number taken at the player's jth information set. To illustrate, here we create the reduced normal form of the game of poker encountered earlier.

GCL1:= e:=LoadEfg["poker.efg"]
GCL2:= << Name[Actions[e]]
{ { { Raise, Fold }, { Raise, Fold } },
  { { Meet, Pass } } }
GCL3:= n:=Nfg[e];
GCL4:= << Name[Strategies[n]]
{ { 11, 12, 21, 22 },
  { 1, 2 } }

In the normal form game, player 1 has four strategies. Player 1's second strategy has name 12. This indicates that the player took action 1 (Raise) in the first information set, and action 2 (Fold) in the second information set.

When a normal form game n is created from an extensive form game, the GCL will ``remember'' the extensive form game that n is associated with, as long as neither the extensive or normal form game is edited. Any mixed strategy solutions computed on the normal form game n can be converted back to a behavior strategy of the game e by using the command Behav. Thus

n := Nfg[e];
m := EnumMixedSolve[n];
b := Behav[m]
will convert the game e to reduced normal form, solve it using the EnumMixedSolve algorithm, and then convert all mixed profiles found back to behavior profiles, and display the list, b of behavior profiles found. The above can also be done in one command without saving intermediate steps as follows:
b := Behav[EnumMixedSolve[Nfg[e]]]

Solving games

Every finite game has at least one Nash equilibrium in either pure or mixed strategies [Nas50]. Various refinements of Nash equilibrium are frequently used to select reasonable equilibria in games with multiple equilibria. The most commonly studied refinements are perfect and proper equilibria for normal form games, and subgame perfect and sequential equilibria for extensive form games. [1]

The best way to compute an equilibrium depends on many factors, the most important of which are the number of players, the number of equilibrium you want to find, and what kind of refinement you are looking for. For a detailed discussion of these issues, see [McKMcL96]. In general, it is easier to solve two person games than n-person games, it is easier to find one equilibrium than to find all, and it is easier to find a Nash equilibrium than a refinement.

The computational complexity of solving for equilibria of games also typically at least exponential in the number of strategies or actions. Consequently, you will find it quite easy to build games in Gambit which cannot be solved (in any reasonable amount of time) by Gambit.

When solving games of any reasonable size, it is therefore good to try and simplify things as much as possible before launching into a solution algorithm. One way of simplifying a game is by reducing the size of the strategy set by elimination of dominated strategies. For extensive form games, a second way of simplifying the problem is by taking account of the subgame structure of the game, and then recursively solve the game from the end.

Supports and dominance elimination

The GCL data types NFSUPPORT and EFSUPPORT are used to represent a support in a normal or extensive form game. A support for a normal form game is a selection of non-empty subsets of strategies for all players in the game. A support for an extensive form game is a selection of non-empty subsets of actions for all information sets in the game.

The main use of supports is to represent the sets of strategies that remain after dominated strategies have been eliminated from the game. All of the built-in functions for solution algorithms in the GCL take an NFSUPPORT or EFSUPPORT as their first parameter, hence can be run on any support of the game.

The call Support[g] returns the full support of the normal or extensive form game g. The full support is the support in which no strategies (or actions) have been eliminated. The function UnDominated can be used to find the dominated strategies or strategies in a support of a game. UnDominated returns a support containing the undominated strategies for each player (or actions for each information set, in the case of extensive for games). By default weak domination is used, and only domination by pure strategies is considered. By setting one or both of the optional parameters strong and mixed to True, strong domination can be used, and domination by mixed strateies can be considered. [2] The following sequence of expressions shows the computation of the full supports and the support resulting from weak dominance elimination in the extensive and reduced normal form of the poker example of the previous chapter.

GCL1:= e:=LoadEfg["poker.efg"]
GCL2:= efsupp:=UnDominated[e]
GCL3:= << Name[Actions[e]]
{ { { Raise, Fold }, { Raise, Fold } },
  { { Meet, Pass } } }
GCL4:= << Name[Actions[efsupp]]
{ { { Raise }, { Raise, Fold } },
  { { Meet, Pass } } }
GCL5:= n:=Nfg[e];
GCL6:= nfsupp:=UnDominated[n];
GCL7:= << Name[Strategies[n]]
{ { 11, 12, 21, 22 },
  { 1, 2 } }
GCL8:= << Name[Strategies[nfsupp]]
{ { 11, 12 },
  { 1, 2 } }

In the above example, for the extensive form game, the action with name "Fold" is dominated, and eliminated by UnDominated. Correspondingly, in the reduced normal form game, the strategies in which the first player takes the second action at the first information set is eliminated.

A user defined function IterativeUnDominated can be used to iteratively eliminate dominated strategies in a game, until no further dominance elimination is possible. This function returns the final support. So the program

n:=LoadNfg["mygame.nfg"];
s:=IterativeUnDominated[n,strong->True,mixed->True];
will find the set of all strategies that remain after iterative elimination by mixed strategies of strongly dominated strategies in the game n.

While the main use of supports is to represent strategies that remain after dominance elimination, you can also construct your own support for a game using the functions RemoveStrategy and AddStrategy.

Subgames

For extensive form games, Gambit recognizes and supports the notion of a subgame. If efg is an extensive form game, the call Subgames[efg] returns a list of nodes representing the roots of valid subgames.

You can control the way the extensive form solution algorithms deal with subgames by ``marking'' or ``unmarking'' subgames. All of the extensive form solution algorithms recursively solve the extensive form game by subgames, but only for subgames that are marked. Terminal marked subgames are solved first, and then for any solution of the subgame, the parent game is pruned, plugging in the continuation value generated by the terminal subgame. The marked subgames that are now terminal are then recursively solved in a similar manner, and so on, until the game starting at the root node is reached. Be warned that if there are multiple equilibria to each subgame, the size of the set of solutions to the full game that are generated by this procedure can be exponential with the number of subgames.

When you first construct a game, the only subgame that is marked is the root node of the tree. This node always represents a valid subgame, and it is not possible to unmark the root node. If node is the root of a valid non-trivial subgame, then the functions MarkSubgame and UnMarkSubgame can be used to mark and unmark the specific subgames starting at that node. MarkedSubgamd can be used to check if the subgame is marked. The user defined functions MarkSubgames and UnMarkSubgames can be used to mark and unmark all valid subgames in the game. MarkedSubgames returns a lsit of root nodes of all currently marked subgames.

The technique of marking subgames can be used to control whether a solution algorithm that finds Nash equilibria returns any Nash equilibrium or only subgame perfect Nash equilibria of the game. If no subgames are marked, the algorithm will return Nash equilibria which may not be subgame perfect. If you first mark all subgames, the algorithm will return subgame perfect equilibria.

Mixed and behavior strategy profiles

The data types MIXED and BEHAV are used to represent mixed and behavior strategy profiles for normal and extensive form games, respectively. Mixed and behavior strategy profiles can be defined on any support of the game. A mixed strategy profile is a specification of a numeric value (usually interpreted as a probability) for each strategy in the support. Similarly, a behavior strategy profile is a specification of a numeric value (usually interpreted as a probability) for each action in the support.

The simplest way of generating a mixed profile for a game is to use the built-in function Centroid, which generates a mixed or behavior strategy profile in which every player adopts each of their strategies (or each action in an information set) with equal probability. For example, if g is a variable representing an extensive or normal form game, and s is a support for the game g, then the calls Centroid[g] or Centroid[s] generate mixed strategy profiles for the game and support, respectively. You can use the function SetStrategyProbs SetActionProbs to change the strategy probabilites for a mixed or behavior profile. You can also use the standard user defined functions Mixed or Behav to generate a mixed profile from a nested list of numeric data, as long as the nested list is of the correct dimensions.

Basic arithmetic operations are defined on mixed and behavior profiles as well. So you can take linear combinations of mixed profiles to create new mixed profiles, as illustrated in this example:

GCL1:= n:=Nfg[{{{3,1},{0,0}},{{0,1},{3,0}},{{1,0},{1,3}}}];
GCL2:= << c:=Centroid[n]
(Mixed) { 1/3 1/3 1/3 }{ 1/2 1/2 }
GCL3:= << cc:=Mixed[n,{{1,0,0},{1,0}}]
(Mixed) { 1 0 0 }{ 1 0 }
GCL4:= << m:=1/2*c+1/2*cc
(Mixed) { 2/3 1/6 1/6 }{ 3/4 1/4 }

In most cases, the value assigned to an action or strategy is interpreted as the probability with which a player adopts the corresponding action or strategy. However, the data for MIXED or BEHAV need not be legitimate probabilities. For example, it would be valid to create a mixed profile using the call Mixed[n,{{1,2,3},{4,5}}]. Probabilities are not required to add up to one, or even to be positive. This feature is especially useful in econometric analysis, as the MIXED and BEHAV data types can be used to represent choice frequencies of corresponding actions or strategies.

All of the solution algorithms that operate on games or their supports return lists of mixed or behavior profiles to representing the solutions. Some algorithms compute important additional information about the profile that may not be recoverable from knowledge of just the strategy probabilies. Consequently, the MIXED an BEHAV data types keep track of who created them, and what properties are known about them. A series of functions are available to query profiles to return this information. These functions are listed in section on ``information about solutions'' in the Categorical Function Reference chapter. To view all of the information that is known about a mixed or behavior profile, you can change the format by which solutions are displayed using the Format function.

Notes

[1]

Definitions of perfect and subgame perfect equilibria are from [Sel75], proper equilibrium from [Mye78], and sequential equilibrium from [KreWil82]. See [vanD83] or [Mye91] for general treatments of refinements.

[2]

Elimination by mixed strategies is only implemented for normal form games.