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 symbolic counting #57

Merged
merged 4 commits into from
Apr 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.x
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ ubuntu-latest, windows-latest, macOS-latest ]
os: [ ubuntu-latest, windows-latest ]
steps:
- uses: actions/checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v2
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.x
Expand Down
80 changes: 50 additions & 30 deletions Src/Core/Solver/Execution/TermEncIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,47 +336,67 @@ public Z3Expr GetTerm(Term t, out Term normalizedTerm, SymExecuter facts = null)

private Z3Expr GetSymCountExpr(SymExecuter facts, Term x, IEnumerable<Z3Expr> ch)
{
// 1. Add the base count
List<Z3ArithExpr> exprs = new List<Z3ArithExpr>();
exprs.Add((Z3ArithExpr)ch.ElementAt(0));

// 2. Create an ITE for each term.
// If a term's constraints are satisfied, the count is incremented by 1
int index = ((int)((Rational)((BaseCnstSymb)x.Args[1].Symbol).Raw).Numerator);
Term comprTerms = facts.GetSymbolicCountTerm(x.Args[2], index);
List<Z3BoolExpr> allBoolExprs = new List<Z3BoolExpr>();
for (int i = 2; i < comprTerms.Args.Count(); i++)

int numTerms = comprTerms.Args.Count() - 2;
Z3Expr[] termExprs = new Z3Expr[numTerms];
Z3BoolExpr[] boolExprs = new Z3BoolExpr[numTerms];
Term normalized;

for (int i = 0; i < comprTerms.Args.Count() - 2; i++)
{
Z3BoolExpr boolExpr = facts.GetSideConstraints(comprTerms.Args[i]);
allBoolExprs.Add(boolExpr);
exprs.Add((Z3ArithExpr)facts.Solver.Context.MkITE(boolExpr,
facts.Solver.Context.MkInt(1),
facts.Solver.Context.MkInt(0)));
var e1Term = comprTerms.Args[i + 2].Args[0];
termExprs[i] = GetTerm(e1Term, out normalized, facts);
boolExprs[i] = facts.GetSideConstraints(comprTerms.Args[i + 2]); // TODO: check if we need comprTerms.Args[i + 2].Args[0] here
}

// 3. The equality between any two terms decrements the count by 1
Term normalized;
for (int i = 0; i < allBoolExprs.Count; i++)
int numCoeffs = (2 * numTerms) - 1;
int[] coeffs = new int[numCoeffs];
Z3BoolExpr[] args = new Z3BoolExpr[numCoeffs];
Z3BoolExpr[] pbTerms = new Z3BoolExpr[numTerms + 1];

for (int i = 0; i < numTerms; i++)
{
for (int j = i + 1; j < allBoolExprs.Count; j++)
coeffs[i] = 1;
args[i] = boolExprs[i];
}

for (int i = 0; i < numTerms - 1; i++)
{
int currIndex = numTerms + i;
Z3BoolExpr currExpr = null;
List<Z3BoolExpr> currExprs = new List<Z3BoolExpr>();
for (int j = i + 1; j < numTerms; j++)
{
var e1Term = comprTerms.Args[i + 2].Args[0];
var e2Term = comprTerms.Args[j + 2].Args[0];
currExpr = facts.Solver.Context.MkEq(termExprs[i], termExprs[j]);
currExpr = facts.Solver.Context.MkAnd(currExpr, boolExprs[i]);
currExpr = facts.Solver.Context.MkAnd(currExpr, boolExprs[j]);
currExprs.Add(currExpr);
}

var e1Enc = GetTerm(e1Term, out normalized, facts);
var e2Enc = GetTerm(e2Term, out normalized, facts);
coeffs[currIndex] = -1;
args[currIndex] = facts.Solver.Context.MkOr(currExprs);
}

var e1 = facts.Solver.Context.MkEq(e1Enc, e2Enc);
var e2 = allBoolExprs.ElementAt(i);
var e3 = allBoolExprs.ElementAt(j);
var e4 = facts.Solver.Context.MkAnd(new Z3BoolExpr[] { e1, e2, e3 });
exprs.Add((Z3ArithExpr)facts.Solver.Context.MkITE(e4,
facts.Solver.Context.MkInt(-1),
facts.Solver.Context.MkInt(0)));
}
for (int i = 0; i < numTerms + 1; i++)
{
pbTerms[i] = facts.Solver.Context.MkPBEq(coeffs, args, i);
}

return facts.Solver.Context.MkAdd(exprs);
return MakeCardConstraint(facts, pbTerms, numTerms);
}

private Z3ArithExpr MakeCardConstraint(SymExecuter facts, Z3BoolExpr[] constraints, int index)
{
if (index == 0)
{
return (Z3ArithExpr)facts.Solver.Context.MkITE(constraints[index], facts.Solver.Context.MkInt(index), facts.Solver.Context.MkInt(-1));
}
else
{
return (Z3ArithExpr)facts.Solver.Context.MkITE(constraints[index], facts.Solver.Context.MkInt(index), MakeCardConstraint(facts, constraints, index - 1));
}
}

public void Debug_Print()
Expand Down
Loading