tell me oh muse, of that ingenious bot that cooperates with itself--
I was writing about FairBot, which cooperates with any bot that it can prove cooperates with it in a one-shot Prisoner's Dilemma tournament, and I said some stuff about hierarchical truth tables which didn't really make sense so I had to go back and work it out properly, or at least in a way that I like. So!
consider this square matrix, where each row represents a bot in the game and 1 is cooperation and 0 is defection; it's an adjacency matrix for a graph where the bots are nodes, rows are outgoing edges and columns are incoming edges, and the existence of a directed edge from one node to another represents cooperation:
C is CooperateBot, which cooperates with everyone, D is DefectBot, which cooperates with no one, and F is FairBot, which cooperates with every bot where the cooperation is mutual; note that the row and column for F are identical!
FairBot is pleasingly symmetrical and it certainly seems altruistic for it to reciprocate like that, but if we want to win this game we might note that it's not strictly necessary to cooperate with CooperateBot, given that it is happy to cooperate with everyone, even DefectBot! let's create a PrudentBot that is mostly fair but defects against oblivious bots:
you can see that PrudentBot wins more than any other bot so far given that it has two outgoing cooperation edges and three incoming; I haven't bothered calculating the actual score for these bots based on the game weights but it's clear that this strategy dominates FairBot and the others.
now we have four bots, but can we add more? and how many bots exist in total? an infinite number of them! in fact an uncountably infinite number of bots, as we can always add a new bot with unique behaviour by a process of diagonalisation similar to that used to prove the uncountability of the real numbers; thankfully we are going to start writing programs which are at least only countably infinite.
the matrix is growing unwieldy so let's switch to defining bots with simple expressions that apply constraints to matrix rows:
1 and 0 are the constant rows (cooperate/defect with everyone), while FairBot is defined by the recursive fixpoint F = Reflect(F), where the Reflect operator transposes a column into a row:
so FairBot(X) is just X(FairBot), the expected symmetry, and then PrudentBot breaks that symmetry by cooperating only with bots that cooperate with it and don't also cooperate with DefectBot, a clear sign that they are imprudent.
this gives us a nice little language for recursively defining bots in terms of functions over bots to booleans:
R is the expression language for bots, keep in mind that each term represents a function that is also an entire row of the matrix (the notation is simplified in the way that we've omitted all the indices, something that usually drives me nuts as a programmer, but it would clutter up the syntax to add them, so constants are actually constant functions and so on).
phi represents an individual boolean value, we will get to why we need that (and C conditions!) later, promise.
I'm going to assert without evidence at this time that there exists a decidable algorithm for taking a set of bot definitions and solving the constraints to calculate the adjacency matrix, although we do need to specify that fix denotes the greatest fixpoint, so any unspecified choice defaults to cooperation, which is needed to ensure FairBot cooperates with itself (the mythical attentive reader may have noticed that without this constraint it would be equally acceptable for FairBot to defect against itself and still satisfy mutuality).
we can explore more interesting possibilities than PrudentBot that I will hopefully get to tomorrow, but I think this formalism is a convenient and fun way of exploring the nature of this cooperation game.