% file: nash1.pl (was: fixpo.pl) % created: 16 Oct 2002. % modified: 20-22 Oct 2002. % modified: 31 Oct, 2 Nov 2002. % modified: 9-11 Jan 2003. game/4 and nash/4 has extended for N-person. % And dominance, undominated, etc has added. % modified: 25,30 Jan, 2003. % modified: 1 Feb, 2003. headline:- write('% ------------------------------------------------------------ %'),nl, write('% simulating the theory of games (1): %'),nl, write('% Nash, mixed, and undominated strategy equilibrium. %'),nl, write('% ------------------------------------------------------------ %'),nl, h0. h0:- write('% nash(G,J,N,S,P):- a Nash strategy of the player J,'),nl, write('% nash(G,N,S,P):- a Nash equilibrium of the game G,'),nl, write('% dominance(G,J,N,S,P):- a dominant stratgy of the player,'),nl, write('% dominance(G,N,S,P):- a dominant stratgy profile,'),nl, write('% nash(mixed(G),N,S,P):- an approximated mixed equilibrium,'),nl, write('% fp(G,[TX,TY],K):- a fixed point of Nash map for the game,'),nl, write('% nash(fixed(G),N,S,P):- a fixed point is an equilibrium,'),nl, write('% undominated(G,N,S,P):- an undominated strategy profile,'),nl, write('% h0:- this.'),nl. :- dynamic game/4. :- dynamic current_model/1. current_model(g1). probability_steps(2). precision(5). :- headline. % ----------------------------------------------------------- % % games % ----------------------------------------------------------- % games(Y):- findall(G,game(G,form(_),_,_),X), sort(X,Y). % a 2-person game of standard form which represents a game tree below. game(g40,form(standard), players([1,2]), acts([(1,[(a1,l),(a1,r),(b1,l),(b1,r)]), (2,[a2,b2])])). game(g40,payoff,[(a1,l),a2],[2,5]). game(g40,payoff,[(a1,r),a2],[2,5]). game(g40,payoff,[(b1,l),a2],[4,1]). game(g40,payoff,[(b1,r),a2],[0,0]). game(g40,payoff,[(a1,l),b2],[2,5]). game(g40,payoff,[(a1,r),b2],[2,5]). game(g40,payoff,[(b1,l),b2],[0,0]). game(g40,payoff,[(b1,r),b2],[1,4]). /* game tree of g40(cf.,Bicchieri(1993), p.101. figure 3.6) b1 b2 [1]------->[2]------>[1]----->[1,4] a1 | | . | r | a2| . l V V | . [0,0] [2,5] V. r        [1]----->[0,0] | l V [4,1] */ % a 3-person game of standard form game(g30,form(standard), players([1,2,3]), acts([(1,[a1,a2]), (2,[b1,b2]), (3,[c1,c2])])). game(g30,payoff,[a1,b1,c1],[2,1,0]). game(g30,payoff,[a1,b2,c1],[0,0,0]). game(g30,payoff,[a2,b1,c1],[0,0,0]). game(g30,payoff,[a2,b2,c1],[1,2,0]). game(g30,payoff,[a1,b1,c2],[1,2,1]). game(g30,payoff,[a1,b2,c2],[0,0,1]). game(g30,payoff,[a2,b1,c2],[0,0,1]). game(g30,payoff,[a2,b2,c2],[2,1,1]). % game(G,players(N),acts(A),payoffs(P)):- game(G,form(standard),players(N),_), game(G,payoff,A,P). % re-utilization of game/3 (/2) of fixpo.pl game(G,players([1,2]),acts([A,B]),payoffs([P1,P2])):- game(G,[player(1,act(A)),player(2,act(B))],payoffs([P1,P2])). game(G,form(S),players([1,2]),acts([(1,[a1,a2]),(2,[b1,b2])])):- member(G,[g0,g1,g2,g3,g4,g5,g6]), S = standard. game(G,payoff,[A,B],[P1,P2]):- member(G,[g0,g1,g2,g3,g4,g5,g6]), game(G,[player(1,act(A)),player(2,act(B))],payoffs([P1,P2])). game(G,players([1,2]),fixed([X,Y]),exp_payoffs([E1,E2])):- current_model(G), fp(G,[X,Y],_K), exp_payoff(G,1,E1,[X,Y]), exp_payoff(G,2,E2,[X,Y]). game(mixed(G),players([1,2]),acts([X,Y]),payoffs([E1,E2])):- mixed_strategies(G,[X,Y]), exp_payoff(G,1,E1,[X,Y]), exp_payoff(G,2,E2,[X,Y]). game(undoms(G,T),form(standard), players(N), acts(A)):- undominated(T,G,N,_,_)->true, setof(B,P^undominated(T,G,N,B,P),A). game(undoms(G,T),players(N),acts(A),payoffs(P)):- undominated(T,G,N,A,P). % % strategy space for each agent % ----------------------------------------------------------- % acts(G,I,S):- game(G,form(_),players(N),acts(A)), nth1(K,N,I), nth1(K,A,(I,S)). % % payoffs for each agent % ----------------------------------------------------------- % payoff(G,J,S,U):- game(G,payoff,S,P), game(G,form(_),players(N),_), nth1(K,N,J), nth1(K,P,U). % % ----------------------------------------------------------- % % Nash strategy equilirium and other solution concepts % ----------------------------------------------------------- % mutate(G,S,J,S1):- game(G,players(N),acts(S),_), game(G,players(N),acts(S1),_), subtract(N,[J],NJ),%write(remains(NJ)),nl, forall(member(J1,NJ), ( nth1(K,N,J1),%write(j1(J1,k(J))), nth1(K,S,SK),%write(s(SK)), nth1(K,S1,SK1),%write(s1(SK1)),nl, SK = SK1 ) ). % modified: 30 Jan 2003. best_response(G,J,N,S,P):- game(G,players(N),acts(S),payoffs(P)), member(J,N), \+ defeated_by(G,J,N,[S,P],_). defeated_by(G,J,N,[S,P],[S1,P1]):- game(G,players(N),acts(S),payoffs(P)), nth1(K,N,J), ( mutate(G,S,J,S1), game(G,players(N),acts(S1),payoffs(P1)), nth1(K,P1,PK1), nth1(K,P,PK), PK < PK1 ). nash(G,J,N,S,P):- best_response(G,J,N,S,P). % nash(G,N,S,P):- game(G,players(N),acts(S),payoffs(P)), \+ (member(J,N), \+ best_response(G,J,N,S,P)). nash(fixed(G),N,S,E):- game(G,players(N),fixed(S),exp_payoffs(E)). %nash(fixed(G),[1,2],[X,Y],[E1,E2]):- % game(G,[X,Y],exp_payoffs([E1,E2])). % dominance(G,J,N,S,P):- game(G,players(N),acts(S),payoffs(P)), nth1(K,N,J), nth1(K,S,SJ), \+ ( game(G,players(N),acts(S1),payoffs(P1)), nth1(K,S1,SJ), \+ ( best_response(G,J,N,S1,P1) ->true; (nl,tab(2),write(defeated_by(S1,P1)),fail) ) ). dominance(G,N,S,P):- game(G,players(N),acts(S),payoffs(P)), \+ (member(J,N), \+ dominance(G,J,N,S,P)). % % iterated dominance % ----------------------------------------------------------- % % modified: 25, 30 Jan 2003. dominate(strong,G,J,SJ,DJ):- % game(G,form(standard),players(N),_), % \+ G =.. [mixed,_], action_pair(G,J,[SJ/_S,PJ],[DJ/_D,PDJ]), PJ > PDJ, \+ ( game(G,players(N),acts(S1),payoffs(P1)), nth1(K,S1,SJ), nth1(K,P1,P1J), game(G,players(N),acts(S2),payoffs(P2)), nth1(K,S2,DJ), nth1(K,P2,P2J), P2J > P1J ). dominate(weak,G,J,SJ,DJ):- % game(G,form(standard),players(N),_), % \+ G =.. [mixed,_], action_pair(G,J,[SJ/_S,PJ],[DJ/_D,PDJ]), \+ PJ > PDJ, \+ ( game(G,players(N),acts(S1),payoffs(P1)), nth1(K,S1,SJ), nth1(K,P1,P1J), game(G,players(N),acts(S2),payoffs(P2)), nth1(K,S2,DJ), nth1(K,P2,P2J), P2J > P1J ). dominated(T,G,J,S,D):- dominate(T,G,J,D,S). undominated(T,G,N,S,P):- game(G,players(N),acts(S),payoffs(P)), %\+ G =.. [mixed,_], member(T,[weak,strong]), \+ ( nth1(K,N,J), nth1(K,S,SJ), dominated(T,G,J,SJ,_D) ). action_pair(G,J,[SJ/S,PJ],[DJ/D,PDJ]):- game(G,players(N),acts(S),payoffs(P)), nth1(K,N,J), nth1(K,S,SJ), nth1(K,P,PJ), mutate(G,S,J,D), game(G,players(N),acts(D),payoffs(PD)), nth1(K,D,DJ), DJ \= SJ, nth1(K,PD,PDJ). % % ----------------------------------------------------------- % % mixed strategy and expected payoff % ----------------------------------------------------------- % % mixed strategy profile --> probability of each outcome mixp_precision(5). mixed_strategies(G,[P1,P2]):- game(G,form(standard),players([1,2]),acts([(1,A1),(2,A2)])), length(A1,M1), length(A2,M2), mixp_precision(L), make_a_prob(P1,base(M1),steps(L)), make_a_prob(P2,base(M2),steps(L)). exp_payoff(G,J,E,P):- findall(V, ( payoff(G,J,S,U), % wn(payoff(G,J,S,U)), index_of_acts(G,S,Index), % wn(act(Index)), index_of_tuple(P,P1,Index),% wn(p(P1)), product(P1,Q), % wn(q(Q)), V is U * Q %,wn(v(V)),nl ), Vs), sum(Vs,E). % % refer to an act profile. index_of_acts(G,A,Index):- game(G,players(N),acts(A),payoffs(_)), length(N,LN), length(A,LN), length(Index,LN), findall(L, ( nth1(K,N,J), % K-th agent nth1(K,A,AJ), acts(G,J,SJ), nth1(L,SJ,AJ) ), Index). % % ----------------------------------------------------------- % % Arithmetic and so on including probabilistic operators % ----------------------------------------------------------- % % % sum % ----------------------------------------------------------- % sum([],0). sum([X|Members],Sum):- sum(Members,Sum1), %number(X), Sum is Sum1 + X. % % product % ----------------------------------------------------------- % product([],1). product([X|Members],Z):- product(Members,Z1), %number(X), Z is Z1 * X. % % allocation % ----------------------------------------------------------- % allocation(N,A,[X|Y]):- allocation(N,A,A,[X|Y]). allocation(0,_,0,[]). allocation(N,A,B,[X|Y]):- integer(A), length([X|Y],N), allocation(_N1,A,B1,Y), % N1 is N - 1, % sum(Y,B1), K is A - B1 + 1, length(L,K), nth0(X,L,X), B is B1 + X. % % probability (percentile) by using allocation % ----------------------------------------------------------- % probabilities(0,[]). probabilities(N,[X|Y]):- integer(N), length([X|Y],N), allocation(N,100,[X|Y]). % % any ratio (weight) can be interpreted into a prob. scale(W,1/Z,P):- findall(Y,(nth1(_K,W,X),Y is X/Z),P). probabilities(W,N,P):- length(W,N), sum(W,Z), scale(W,1/Z,P). % make_a_prob(P,base(M),steps(L)):- var(P), length(P,M), allocation(M,L,W), probabilities(W,M,P). make_a_prob(P,base(M),_):- \+ var(P), length(P,M), \+ ( member(P1,P), ( var(P1); P1 > 1; P1 < 0 ) ), sum(P,1). % % expected value % ----------------------------------------------------------- % expected_value(W,A,E/100):- length(A,N), probability(W,N,P), product_sum(P,A,_,E). % % weighted sum % ----------------------------------------------------------- % product_sum([],[],[],0). product_sum([P|Q],[A|B],[E|F],V):- length(Q,N), length(B,N), product_sum(Q,B,F,V1), E is P * A, V is V1 + E. % % ----------------------------------------------------------- % % Utilities for list operations % ----------------------------------------------------------- % % % index for a tuple. % ----------------------------------------------------------- % % 1) only mention for a direct product of sets. index_of_tuple(B,A,Index):- \+ var(B), \+ var(A), length(B,LN), % base sets length(A,LN), length(Index,LN), findall(L, ( nth1(K,B,BJ), %write(a(K,B,BJ)), nth1(L,BJ,AJ),%write(b(L,BJ,AJ)), nth1(K,A,AJ) %,write(c(K,A,AJ)),nl ), Index). index_of_tuple(B,A,Index):- \+ var(B), \+ var(Index), var(A), length(B,LN), % base sets length(Index,LN), length(A,LN), findall(AJ, ( nth1(K,B,BJ), nth1(K,Index,L), nth1(L,BJ,AJ) ), A). % % descending/ascending natural number sequence less than N. % ----------------------------------------------------------- % dnum_seq([],N):-N<0,!. dnum_seq([0],1). dnum_seq([A|Q],N):- A is N - 1, length(Q,A), dnum_seq(Q,A). anum_seq(Aseq,N):-dnum_seq(Dseq,N),sort(Dseq,Aseq). % % inquire the goal multiplicity % ----------------------------------------------------------- % sea_multiple(Goal,Cond,N,M):- Clause=..Goal, findall(Cond,Clause,Z),length(Z,N),sort(Z,Q),length(Q,M). % bag0([],_A,0). bag0([C|B],A,N):- length([C|B],N), bag0(B,A,_N1), member(C,A). zeros(Zero,N):-bag0(Zero,[0],N). ones(One,N):-bag0(One,[1],N). % % subset_of/3 : subset-enumeration % ----------------------------------------------------------- % subset_of(A,N,As):- length(As,L), length(D,L), list_projection(D,As,B), length(B,N), sort(B,A). % a sequence of binary choice for a list: %-------------------------------------------------- list_projection([],[],[]). list_projection([X|Y],[_A|B],C):- X = 0, list_projection(Y,B,C). list_projection([X|Y],[A|B],[A|C]):- X = 1, list_projection(Y,B,C). % % ----------------------------------------------------------- % % Utilities for outputs % ----------------------------------------------------------- % % % write and new line. % ----------------------------------------------------------- % wn(X):-write(X),nl. % % output to file. % ----------------------------------------------------------- % tell_test(Goal):- open('tell.txt',write,S), tell('tell.txt'), Goal, current_stream('tell.txt',write,S), tell(user),wn(end), close(S). % % %******************************** % cited from previous version (fixpo.pl) %******************************** % with minor modifications. % %-------------------------------------------- % continuous map by Nash (1951) %-------------------------------------------- % c[k]=max(v1([s1[k],Y])-v1([X,Y]),0), % d[k]=max(v2([X,s2[k]])-v1([X,Y]),0), % X'[k]=(X[k]+c[k])/(1+c[1]+...+c[K1]), % Y'[k]=(Y[k]+d[k])/(1+d[1]+...+d[K2]). % nash_map(G,c(1,C),[X,Y]):- exp_payoff(G,1,E,[X,Y]), exp_payoff(G,1,E1,[[1,0],Y]), C0 is E1 - E, (C0 > 0 -> C = C0; C =0). nash_map(G,c(2,C),[X,Y]):- exp_payoff(G,1,E,[X,Y]), exp_payoff(G,1,E1,[[0,1],Y]), C0 is E1 - E, (C0 > 0 -> C = C0; C =0). nash_map(G,d(1,D),[X,Y]):- exp_payoff(G,2,E,[X,Y]), exp_payoff(G,2,E1,[X,[1,0]]), D0 is E1 - E, (D0 > 0 -> D = D0; D =0). nash_map(G,d(2,D),[X,Y]):- exp_payoff(G,2,E,[X,Y]), exp_payoff(G,2,E1,[X,[0,1]]), D0 is E1 - E, (D0 > 0 -> D = D0; D =0). % % it is important that this predicate has separated from updated. nash_map(G,[C1,C2],[D1,D2],[X,Y]):- nash_map(G,c(1,C1),[X,Y]),%wn(C1), nash_map(G,c(2,C2),[X,Y]),%wn(C2), nash_map(G,d(1,D1),[X,Y]),%wn(D1), nash_map(G,d(2,D2),[X,Y]),%wn(D2), !. updated(G,[TX,TY],[X,Y],[[C1,C2],[D1,D2]]):- % prob(X,base(2),_), % prob(Y,base(2),_),%wn(prob(X,Y)), forall(member(P,X),\+var(P)),%wn(ok1), forall(member(P,Y),\+var(P)),%wn(ok2), nash_map(G,[C1,C2],[D1,D2],[X,Y]), X=[X1,X2], Y=[Y1,Y2], SC is 1 + C1 + C2, SD is 1 + D1 + D2, TX1 is (X1 + C1) / SC, TX2 is (X2 + C2) / SC, TY1 is (Y1 + D1) / SD, TY2 is (Y2 + D2) / SD, TX=[TX1,TX2], TY=[TY1,TY2]. % % a pair of the first coordinate probabilities, each vector of distribution p2(X,Y):- X=[[A,_A1],[B,_B1]],Y=[A,B]. p2(X):-p2(_,X). print_seri:- path_of_map(_G,B,A,_C,D),p2(B,PB),p2(A,PA), write((tp(PB,'exp_gains_against_pure'(D)):-p(PA))),wn('.'). path_of_map(_G,[X,Y],[X,Y],[[X1],[Y1]],[[0,0],[0,0]]):- probability_steps(ST), make_a_prob(X,base(2),steps(ST)), make_a_prob(Y,base(2),steps(ST)), p2([X,Y],[X1,Y1]). % X=[X1,_], Y=[Y1,_]. path_of_map(G,[TX,TY],[X,Y],H0):- path_of_map(G,[TX,TY],[X,Y],H0,_E0). path_of_map(G,[TX,TY],[X,Y],[[TX1|H1],[TY1|H2]]):- path_of_map(G,[Z1,Z2],[X,Y],[H1,H2]), updated(G,[TX,TY],[Z1,Z2],_), \+converge(G,[TX,TY],[Z1,Z2]),%wn((p(X,Y),t(TX,TY))),%read(y), p2([TX,TY],[TX1,TY1]),%wn('%!'), length(H1,L),write(level(L)),nl, (is_a_long_trip(L) -> (write(non_fxp(L,[Z1,Z2])),nl, write(' its a so long trip. tired?'),read(y)->!,fail);true). is_a_long_trip(L):- L >=30. is_a_very_long_trip(L):- L >=50. % %-------------------------------------------- % fixed point of the map --> Nash equilibrium %-------------------------------------------- fp(G,[TX,TY],K):- fixed_point(G,[TX,TY],K). fixed_point(G,[TX,TY],L):- path_of_map(G,[Z1,Z2],_,[H1,_]), updated(G,[TX,TY],[Z1,Z2],_), converge(G,[TX,TY],[Z1,Z2]), length(H1,L),write(level(L)),nl, (is_a_long_trip(L) -> (write(fxp(G,L,[Z1,Z2])),nl, write(' its a so long trip. tired?'),read(y)->!,fail);true). converge(G,[TX,TY],[X,Y]):- precision(M), converge1(G,[TX,TY],[X,Y],M). converge1(G,[TX,TY],[X,Y],M):- exp_payoff(G,1,E1,[X,Y]), exp_payoff(G,2,E2,[X,Y]), exp_payoff(G,1,F1,[TX,TY]), exp_payoff(G,2,F2,[TX,TY]), P1 is integer(E1 * (10^M)), P2 is integer(E2 * (10^M)), Q1 is integer(F1 * (10^M)), Q2 is integer(F2 * (10^M)), S1 is (Q1-P1)^2, S2 is (Q2-P2)^2,write((e(F1-E1,F2-E2),d(S1,S2))),nl,%read(y), S is S1 + S2, S < 5. converge2(_,[[TX,_],[TY,_]],[[X,_],[Y,_]],M):- TXP is integer(TX * (10^M)), TYP is integer(TY * (10^M)), XP is integer(X * (10^M)), YP is integer(Y * (10^M)), S is (TXP-XP)^2 + (TYP-YP)^2, S < 1. % %% interface: to display and to change of game payoffs game:- forall( ( G=game([player(1,act(A1)),player(2,act(B1))],payoffs([P1,P2])), G ), ( wn((act(A1,B1),'-->',payoffs(P1,P2))) ) ). set_payoffs:- forall( ( G=game(GN,[player(1,act(A1)),player(2,act(B1))],payoffs([P1,P2])), G ), ( write('the current model: '),write(GN),nl, tab(4),wn((act(A1,B1)-->payoffs(P1,P2))), write('change the payoffs ? '),read(U), write('new name of the model: '),read(GN1), (GN=GN1->retract(G);true), ( U=[_,_] -> ( G1=game(GN1,[player(1,act(A1)),player(2,act(B1))],payoffs(U)), assert(G1) );true ) ) ), game. % %-------------------------------------------- % other examples of game in fixpo.pl %-------------------------------------------- % % a game with two pure strategy equilibria. game(g0,[player(1,act(a1)),player(2,act(b1))],payoffs([1,1])). game(g0,[player(1,act(a1)),player(2,act(b2))],payoffs([0,0])). game(g0,[player(1,act(a2)),player(2,act(b1))],payoffs([0,0])). game(g0,[player(1,act(a2)),player(2,act(b2))],payoffs([0,0])). % a game with two pure strategy equilibria. game(g1,[player(1,act(a1)),player(2,act(b1))],payoffs([2,1])). game(g1,[player(1,act(a1)),player(2,act(b2))],payoffs([0,0])). game(g1,[player(1,act(a2)),player(2,act(b1))],payoffs([0,0])). game(g1,[player(1,act(a2)),player(2,act(b2))],payoffs([1,2])). % a game with a pure strategy equilibrium. game(g2,[player(1,act(a1)),player(2,act(b1))],payoffs([1,3])). game(g2,[player(1,act(a1)),player(2,act(b2))],payoffs([1,0])). game(g2,[player(1,act(a2)),player(2,act(b1))],payoffs([2,0])). game(g2,[player(1,act(a2)),player(2,act(b2))],payoffs([3,1])). % a game with no pure strategy equilibrium. game(g3,[player(1,act(a1)),player(2,act(b1))],payoffs([0,3])). game(g3,[player(1,act(a1)),player(2,act(b2))],payoffs([1,0])). game(g3,[player(1,act(a2)),player(2,act(b1))],payoffs([2,0])). game(g3,[player(1,act(a2)),player(2,act(b2))],payoffs([0,1])). % a game with no pure strategy equilibrium. game(g4,[player(1,act(a1)),player(2,act(b1))],payoffs([0,1])). game(g4,[player(1,act(a1)),player(2,act(b2))],payoffs([1,0])). game(g4,[player(1,act(a2)),player(2,act(b1))],payoffs([1,0])). game(g4,[player(1,act(a2)),player(2,act(b2))],payoffs([0,1])). % a game with two pure strategy equilibria. game(g5,[player(1,act(a1)),player(2,act(b1))],payoffs([1,5])). game(g5,[player(1,act(a1)),player(2,act(b2))],payoffs([0,4])). game(g5,[player(1,act(a2)),player(2,act(b1))],payoffs([0,0])). game(g5,[player(1,act(a2)),player(2,act(b2))],payoffs([1,1])). % a game with no pure strategy equilibrium. game(g6,[player(1,act(a1)),player(2,act(b1))],payoffs([1,1])). game(g6,[player(1,act(a1)),player(2,act(b2))],payoffs([2,0])). game(g6,[player(1,act(a2)),player(2,act(b1))],payoffs([2,0])). game(g6,[player(1,act(a2)),player(2,act(b2))],payoffs([1,1])). % % end.