How can we define in a proof assistant (eg., Coq) a notion of a 2-player game, where each player is a program that has access to the opponent's source code?
Background: In Open Source Game Theory, we think about bots that reason about each other (prove theorems), knowing the other's source code. I would like implement such bots in a proof assistant, if possible. (https://arxiv.org/pdf/2208.07006.pdf, Open Problem 4)
What I have in mind would looks like this:
Inductive outcome := Cooperate | Defect.
(* Dupoc is short for Defect Unless Proof of Cooperation *)
Definition Dupoc (n:N) (bot2 : N -> bot -> outcome) : N -> bot -> outcome :=
'try for n steps to find a proof that bot2 n self = Cooperate, if found':
return Cooperate
else
return Defect.
The point is that we want to run the agents together with each other as input:
Definition game n1 bot1 n2 bot2 := (bot1 n1 bot2, bo2 n2 bo1).
Of course, the type bot
does not exist as I have written it. Is there a way to actually make this happen?
The other problem is that the bot's function is trying to find a proof and returning a bool that reflects the success. Is this possible in some proof assistant? The proof assistant would have to have access to its own inner workings somehow, which seems hard.
I think I could solve the problem by having a Coq implementation in Coq.
Then I could have, like in the paper:
Inductive CoqTokens := ...
Definition BotExpression := ... (* A valid expression for a Bot *)
Class Bot := {
play : BotExpression -> outcome,
source : BotExpression (* This should be the source code for 'play' in our Coq-in-Coq implementation *)
}.
Definition game bot1 bot2 := (bot1.play bot2.source, bot2.play bot1.source).
But this seems very much work if it is possible. The Coq implementation in Coq still needs to contain everything about proofing. And I am not sure if it actually solves the problem.