Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix and strategy synthesis for next #13

Open
wants to merge 39 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b9653a0
fix bug in stepEquilibria maxRow/maxCol
gabrielhrs May 8, 2020
011495d
Adds switch for scale factor used when building lps for zero-sum mode…
gabrielhrs May 23, 2020
35f052c
Merge branch 'master' of https://github.com/davexparker/prism-games
gabrielhrs May 23, 2020
fd00c2f
Fix bug with equilibria (unique row/column)
gabrielhrs Oct 28, 2020
c0b22d4
Merge branch 'master' of https://github.com/davexparker/prism-games
gabrielhrs Mar 23, 2021
23b6062
Merge branch 'master' of https://github.com/gabrielhrs/prism-games
gabrielhrs Mar 23, 2021
c88bdc4
Merge branch 'master' of https://github.com/prismmodelchecker/prism-g…
gabrielhrs Mar 23, 2021
da4146c
small fixes (including next operator)
gabrielhrs Mar 24, 2021
bc9b1c6
class for equilibria computation with yices
gabrielhrs Mar 30, 2021
fc29d4e
missing yices linux file
gabrielhrs Apr 3, 2021
5f66a97
yices libraries and refactoring
May 27, 2021
293842b
update linux libraries
gabrielhrs Apr 3, 2021
0413257
missing yices mac file
Jul 7, 2021
1fb699f
Merge branch 'master' of https://github.com/gabrielhrs/prism-games
Jul 7, 2021
03a5aa1
conflicts and merge
Apr 12, 2022
58044f4
Merge branch 'prismmodelchecker-master'
Apr 12, 2022
3bc1f61
small fixes
Apr 12, 2022
32f4fe0
small fixes
Apr 12, 2022
e3279a6
change assumption check for two player equilibria
Apr 25, 2022
0a4bbd7
change assumption check for two player equilibria
Apr 25, 2022
b7bc5e3
change assumption check for two player equilibria
Apr 25, 2022
54e4041
fix null remain for probabilistic
Apr 27, 2022
bec8c13
fix check for probabilistic
Apr 29, 2022
7f86ac5
switch for equilibria assumption check
May 3, 2022
799aaba
Merge branch 'master' of https://github.com/prismmodelchecker/prism-g…
Feb 9, 2023
0ebab2b
Fix and strategy synthesis for next
Feb 10, 2023
4b58ffc
Slightly more relaxed assumptions for equilibria
Feb 13, 2023
f56302f
Improved precomp for until, tidying, commenting
Feb 13, 2023
ac2fedc
Changes to parser and settings for equilibria
Apr 3, 2023
ec09a5f
Disables precomputation for bounded until
gabrielhrs Apr 3, 2023
8a9eab5
Changes to ProbModelChecker for correlated
Apr 11, 2023
042e64f
Merge branch 'master' of https://github.com/gabrielhrs/prism-games
Apr 11, 2023
d86c285
Changes to CSGStrategy to include correlated
Apr 11, 2023
d40d909
Minor changes to Nash equilibria computation classes
Apr 11, 2023
7ecc833
Interface and class for computing correlated equilibria, auxiliary cl…
Apr 11, 2023
5b34741
Changes to CSGModelChecker to handle multi-player equilibria
Apr 11, 2023
2524dac
Changes to CSGModelCheckerEquilibria to include correlated, fair and …
Apr 11, 2023
7c56844
Disables Gurobi
Apr 11, 2023
3ddf50a
Test SWNE/SWCE/SFNE/SFCE two-player
Apr 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions prism-tests/functionality/verify/csgs/nash/test_diff_sw_fr.prism
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
csg

player p1 m1 endplayer
player p2 m2 endplayer

module m1
s : bool init false;
[a1] !s -> (s'=!s);
[b1] !s -> (s'=!s);
endmodule

module m2
[a2] !s -> true;
[b2] !s -> true;
endmodule

rewards "r1"
[a1,a2] !s : 5.0;
[a1,b2] !s : 2.0;
[b1,a2] !s : 6.0;
[b1,b2] !s : 0.0;
endrewards

rewards "r2"
[a1,a2] !s : 5.0;
[a1,b2] !s : 6.0;
[b1,a2] !s : 2.0;
[b1,b2] !s : 1.0;
endrewards

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RESULT: 16/2
<<p1:p2>>{NE,SW}max=?(R{"r1"}[C<=1] + R{"r2"}[C<=1])
// RESULT: 15/2
<<p1:p2>>{NE,FR}max=?(R{"r1"}[C<=1] + R{"r2"}[C<=1])
// RESULT: 44/5
<<p1:p2>>{CE,SW}max=?(R{"r1"}[C<=1] + R{"r2"}[C<=1])
// RESULT: 26/3
<<p1:p2>>{CE,FR}max=?(R{"r1"}[C<=1] + R{"r2"}[C<=1])
Binary file added prism/lib/libyices.2.dylib
Binary file not shown.
Binary file added prism/lib/libyices.so.2.6
Binary file not shown.
Binary file added prism/lib/libyices.so.2.6.1
Binary file not shown.
Binary file added prism/lib/libyices2java.dylib
Binary file not shown.
1 change: 1 addition & 0 deletions prism/lib/libyices2java.jnilib
Binary file added prism/lib/libyices2java.so
Binary file not shown.
Binary file added prism/lib/yices.jar
Binary file not shown.
59 changes: 59 additions & 0 deletions prism/src/explicit/CSGCorrelated.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//==============================================================================
//
// Copyright (c) 2002-
// Authors:
// * Dave Parker <david.parker@cs.ox.ac.uk> (University of Oxford)
// * Gabriel Santos <gabriel.santos@cs.ox.ac.uk> (University of Oxford)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================

package explicit;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;

public interface CSGCorrelated {

/**
* Computes correlated equilibria for a normal form game
*
* @param utilities Utility table as a map from action indexes to utility arrays
* @param ce_constraints An auxiliary mapping of actions to utilities (player i -> action a -> actions of -i -> utility) used to set the constraints for correlated equilibria
* @param strategies Array with individual actions for each player
* @param ce_var_map Map for joint actions
* @param crit Criterion (social-welfare = 3, fair = 4)
*/
public EquilibriumResult computeEquilibrium(HashMap<BitSet, ArrayList<Double>> utilities,
ArrayList<ArrayList<HashMap<BitSet, Double>>> ce_constraints,
ArrayList<ArrayList<Integer>> strategies,
HashMap<BitSet, Integer> ce_var_map, int crit);

/**
* Gets the solver's name
*/
public String getSolverName();

public void clear();

public void printModel();

}
284 changes: 284 additions & 0 deletions prism/src/explicit/CSGCorrelatedZ3.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
//==============================================================================
//
// Copyright (c) 2002-
// Authors:
// * Dave Parker <david.parker@cs.ox.ac.uk> (University of Oxford)
// * Gabriel Santos <gabriel.santos@cs.ox.ac.uk> (University of Oxford)
//
//------------------------------------------------------------------------------
//
// This file is part of PRISM.
//
// PRISM is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// PRISM is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with PRISM; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
//==============================================================================

package explicit;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.HashMap;

import com.microsoft.z3.AlgebraicNum;
import com.microsoft.z3.ArithExpr;
import com.microsoft.z3.BoolExpr;
import com.microsoft.z3.Context;
import com.microsoft.z3.Expr;
import com.microsoft.z3.IntExpr;
import com.microsoft.z3.Model;
import com.microsoft.z3.Optimize;
import com.microsoft.z3.RatNum;
import com.microsoft.z3.RealExpr;
import com.microsoft.z3.Status;
import com.microsoft.z3.Version;

import prism.PrismException;

/**
* Z3-based implementation for correlated equilibria computation
* @author Gabriel Santos
*
*/
public class CSGCorrelatedZ3 implements CSGCorrelated {

private RealExpr[] vars;
private RealExpr[] payoff_vars;
private RealExpr obj_var;
private ArithExpr[] payoffs;

private HashMap<String, String> cfg;
private Context ctx;
private Optimize s;

private IntExpr zero;
private IntExpr one;

private String name;
private int n_coalitions;

/**
* Creates a new CSGCorrelatedZ3 (without initialisation)
*/
public CSGCorrelatedZ3() {
cfg = new HashMap<String, String>();
cfg.put("model", "true");
ctx = new Context(cfg);
s = ctx.mkOptimize();
name = Version.getFullVersion();
}

/**
* Creates a new CSGCorrelatedZ3
* @param n_entries Number of entries in the utility table
* @param n_coalitions Number of coalitions
*/
public CSGCorrelatedZ3(int n_entries, int n_coalitions) {
cfg = new HashMap<String, String>();
cfg.put("model", "true");
cfg.put("auto_config", "true");
ctx = new Context(cfg);
s = ctx.mkOptimize();
name = Version.getFullVersion();
zero = ctx.mkInt(0);
one = ctx.mkInt(1);
vars = new RealExpr[n_entries];
payoffs = new ArithExpr[n_coalitions];
this.n_coalitions = n_coalitions;
for (int i = 0; i < n_entries; i++) {
vars[i] = ctx.mkRealConst("v" + i);
s.Add(ctx.mkLe(vars[i], one));
s.Add(ctx.mkGe(vars[i], zero));
}
payoff_vars = new RealExpr[n_coalitions];
obj_var = ctx.mkRealConst("ob");
}

public EquilibriumResult computeEquilibrium(HashMap<BitSet, ArrayList<Double>> utilities,
ArrayList<ArrayList<HashMap<BitSet, Double>>> ce_constraints,
ArrayList<ArrayList<Integer>> strategies,
HashMap<BitSet, Integer> ce_var_map, int type) {
EquilibriumResult result = new EquilibriumResult();
ArrayList<Double> payoffs_result = new ArrayList<Double>();
ArrayList<Distribution> strategy_result = new ArrayList<Distribution>();
Distribution d = new Distribution();
ArithExpr expr;
BitSet is, js;
double u;
int c, q, r;
is = new BitSet();
js = new BitSet();

s.Push();
expr = ctx.mkInt(0);

// Builds a payoff expression for each player, and one for the sum of all payoffs
for (int i = 0; i < n_coalitions; i++) {
payoffs[i] = zero;
}
for (BitSet e : utilities.keySet()) {
u = 0.0;
for (c = 0; c < n_coalitions; c++) {
u += utilities.get(e).get(c);
payoffs[c] = ctx.mkAdd(payoffs[c], ctx.mkMul(vars[ce_var_map.get(e)], ctx.mkReal(String.valueOf(utilities.get(e).get(c)))));
}
expr = ctx.mkAdd(expr, ctx.mkMul(vars[ce_var_map.get(e)], ctx.mkReal(String.valueOf(u))));
}
for (c = 0; c < n_coalitions; c++) {
payoff_vars[c] = ctx.mkRealConst("p " + c);
s.Add(ctx.mkEq(payoff_vars[c], payoffs[c]));
}

// In case of the fair variant (minimise the difference between the largest and smallest payoffs)
// we first need to add auxiliary constraints
// The default case is social-welfare, in which we just maximise the sum
switch (type) {
case CSGModelCheckerEquilibria.FAIR : {
RealExpr ph;
RealExpr pl;
ph = ctx.mkRealConst("ph"); // Highest payoff
pl = ctx.mkRealConst("pl"); // Lowest payoff
BoolExpr bh;
BoolExpr bl;
// Additional constraints for fair
for (int i = 0; i < n_coalitions; i++) {
bh = ctx.mkTrue();
bl = ctx.mkTrue();
for (int j = 0; j < n_coalitions; j++) {
if (i != j) {
bh = ctx.mkAnd(bh, ctx.mkGe(payoffs[i], payoffs[j]));
bl = ctx.mkAnd(bl, ctx.mkLe(payoffs[i], payoffs[j]));
}
}
s.Add(ctx.mkImplies(bh, ctx.mkEq(ph, payoffs[i])));
s.Add(ctx.mkImplies(bl, ctx.mkEq(pl, payoffs[i])));
}
s.MkMinimize(ctx.mkSub(ph, pl));
break;
}
default : {
// Primary objective is maximising the sum
s.Add(ctx.mkEq(obj_var, expr));
s.MkMaximize(expr);
}
}

// Lower priority objectives of maximising the payoff of each player in decreasing order
for (c = 0; c < n_coalitions; c++) {
s.MkMaximize(payoffs[(c)]);
}

// Constraints for correlated equilibria
for (c = 0; c < n_coalitions; c++) {
for (q = 0; q < strategies.get(c).size(); q++) {
expr = zero;
is.clear();
is.set(strategies.get(c).get(q));
for (r = 0; r < strategies.get(c).size(); r++) {
js.clear();
for (BitSet e : ce_constraints.get(c).get(q).keySet()) {
is.or(e);
js.or(e);
if (q != r) {
js.set(strategies.get(c).get(r));
expr = ctx.mkAdd(expr, ctx.mkMul(vars[ce_var_map.get(is)],
ctx.mkSub(ctx.mkReal(String.valueOf(utilities.get(is).get(c))),
ctx.mkReal(String.valueOf(utilities.get(js).get(c))))));
}
is.andNot(e);
js.andNot(e);
}
if (q != r) {
s.Add(ctx.mkGe(expr, zero));
}
}
}
}

// Sets unused variables to zero
for (c = utilities.size(); c < vars.length; c++) {
s.Add(ctx.mkEq(vars[c], zero));
}

expr = ctx.mkInt(0);
for (c = 0; c < vars.length; c++) {
expr = ctx.mkAdd(expr, vars[c]);
}
s.Add(ctx.mkEq(expr, one));

/*
for (BoolExpr e : s.getAssertions()) {
System.out.println(e);
}
*/

// If and optimal solution is found, set the values and strategies
if (s.Check() == Status.SATISFIABLE) {
for (c = 0; c < vars.length; c++) {
d.add(c, getDoubleValue(s.getModel(), vars[c]));
}
for (c = 0; c < payoff_vars.length; c++) {
payoffs_result.add(getDoubleValue(s.getModel(), payoff_vars[c]));
}
result.setStatus(CSGModelCheckerEquilibria.CSGResultStatus.SAT);
result.setPayoffVector(payoffs_result);
strategy_result.add(d);
result.setStrategy(strategy_result);
}
else {
result.setStatus(CSGModelCheckerEquilibria.CSGResultStatus.UNSAT);
}

s.Pop();
return result;
}

/**
* Return a double value for a given expression (usually variable), converting from BigInt fractions
* @param model The SMT model
* @param expr The SMT expression
* @return
*/
public double getDoubleValue(Model model, Expr expr) {
RatNum v1;
AlgebraicNum v2;
if(model.getConstInterp(expr) instanceof RatNum) {
v1 = (RatNum) model.getConstInterp(expr);
return (Double) (v1.getBigIntNumerator().doubleValue() / v1.getBigIntDenominator().doubleValue());
}
else if (model.getConstInterp(expr) instanceof AlgebraicNum) {
v2 = (AlgebraicNum) model.getConstInterp(expr);
v1 = v2.toUpper(12);
return (Double) (v1.getBigIntNumerator().doubleValue() / v1.getBigIntDenominator().doubleValue());
}
else
return Double.NaN;
}

public String getSolverName() {
return name;
}

@Override
public void clear() {

}

@Override
public void printModel() {
// TODO Auto-generated method stub

}

}
Loading