3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

fixes to Euclidean solver, fixes #100

Signed-off-by: Nikolaj Bjorner <nbjorner@hotmail.com>
This commit is contained in:
Nikolaj Bjorner 2015-05-27 09:21:20 -07:00
commit e483efd3f4
38 changed files with 1017 additions and 563 deletions

View file

@ -98,11 +98,12 @@ namespace Microsoft.Z3
/// <summary> /// <summary>
/// The keys stored in the map. /// The keys stored in the map.
/// </summary> /// </summary>
public ASTVector Keys public AST[] Keys
{ {
get get
{ {
return new ASTVector(Context, Native.Z3_ast_map_keys(Context.nCtx, NativeObject)); ASTVector res = new ASTVector(Context, Native.Z3_ast_map_keys(Context.nCtx, NativeObject));
return res.ToArray();
} }
} }

View file

@ -99,6 +99,138 @@ namespace Microsoft.Z3
return Native.Z3_ast_vector_to_string(Context.nCtx, NativeObject); return Native.Z3_ast_vector_to_string(Context.nCtx, NativeObject);
} }
/// <summary>
/// Translates an AST vector into an AST[]
/// </summary>
public AST[] ToArray()
{
uint n = Size;
AST[] res = new AST[n];
for (uint i = 0; i < n; i++)
res[i] = AST.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into an Expr[]
/// </summary>
public Expr[] ToExprArray()
{
uint n = Size;
Expr[] res = new Expr[n];
for (uint i = 0; i < n; i++)
res[i] = Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a BoolExpr[]
/// </summary>
public BoolExpr[] ToBoolExprArray()
{
uint n = Size;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (BoolExpr) Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a BitVecExpr[]
/// </summary>
public BitVecExpr[] ToBitVecExprArray()
{
uint n = Size;
BitVecExpr[] res = new BitVecExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (BitVecExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a ArithExpr[]
/// </summary>
public ArithExpr[] ToArithExprArray()
{
uint n = Size;
ArithExpr[] res = new ArithExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (ArithExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a ArrayExpr[]
/// </summary>
public ArrayExpr[] ToArrayExprArray()
{
uint n = Size;
ArrayExpr[] res = new ArrayExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (ArrayExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a DatatypeExpr[]
/// </summary>
public DatatypeExpr[] ToDatatypeExprArray()
{
uint n = Size;
DatatypeExpr[] res = new DatatypeExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (DatatypeExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a FPExpr[]
/// </summary>
public FPExpr[] ToFPExprArray()
{
uint n = Size;
FPExpr[] res = new FPExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (FPExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a FPRMExpr[]
/// </summary>
public FPRMExpr[] ToFPRMExprArray()
{
uint n = Size;
FPRMExpr[] res = new FPRMExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (FPRMExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a IntExpr[]
/// </summary>
public IntExpr[] ToIntExprArray()
{
uint n = Size;
IntExpr[] res = new IntExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (IntExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
/// <summary>
/// Translates an ASTVector into a RealExpr[]
/// </summary>
public RealExpr[] ToRealExprArray()
{
uint n = Size;
RealExpr[] res = new RealExpr[n];
for (uint i = 0; i < n; i++)
res[i] = (RealExpr)Expr.Create(this.Context, this[i].NativeObject);
return res;
}
#region Internal #region Internal
internal ASTVector(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); } internal ASTVector(Context ctx, IntPtr obj) : base(ctx, obj) { Contract.Requires(ctx != null); }
internal ASTVector(Context ctx) : base(ctx, Native.Z3_mk_ast_vector(ctx.nCtx)) { Contract.Requires(ctx != null); } internal ASTVector(Context ctx) : base(ctx, Native.Z3_mk_ast_vector(ctx.nCtx)) { Contract.Requires(ctx != null); }

View file

@ -269,14 +269,6 @@ namespace Microsoft.Z3
AST.ArrayLength(queries), AST.ArrayToNative(queries)); AST.ArrayLength(queries), AST.ArrayToNative(queries));
} }
BoolExpr[] ToBoolExprs(ASTVector v) {
uint n = v.Size;
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = new BoolExpr(Context, v[i].NativeObject);
return res;
}
/// <summary> /// <summary>
/// Retrieve set of rules added to fixedpoint context. /// Retrieve set of rules added to fixedpoint context.
/// </summary> /// </summary>
@ -286,7 +278,8 @@ namespace Microsoft.Z3
{ {
Contract.Ensures(Contract.Result<BoolExpr[]>() != null); Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_get_rules(Context.nCtx, NativeObject))); ASTVector av = new ASTVector(Context, Native.Z3_fixedpoint_get_rules(Context.nCtx, NativeObject));
return av.ToBoolExprArray();
} }
} }
@ -299,7 +292,8 @@ namespace Microsoft.Z3
{ {
Contract.Ensures(Contract.Result<BoolExpr[]>() != null); Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_get_assertions(Context.nCtx, NativeObject))); ASTVector av = new ASTVector(Context, Native.Z3_fixedpoint_get_assertions(Context.nCtx, NativeObject));
return av.ToBoolExprArray();
} }
} }
@ -316,21 +310,24 @@ namespace Microsoft.Z3
} }
} }
/// <summary> /// <summary>
/// Parse an SMT-LIB2 file with fixedpoint rules. /// Parse an SMT-LIB2 file with fixedpoint rules.
/// Add the rules to the current fixedpoint context. /// Add the rules to the current fixedpoint context.
/// Return the set of queries in the file. /// Return the set of queries in the file.
/// </summary> /// </summary>
public BoolExpr[] ParseFile(string file) { public BoolExpr[] ParseFile(string file)
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_file(Context.nCtx, NativeObject, file))); {
ASTVector av = new ASTVector(Context, Native.Z3_fixedpoint_from_file(Context.nCtx, NativeObject, file));
return av.ToBoolExprArray();
} }
/// <summary> /// <summary>
/// Similar to ParseFile. Instead it takes as argument a string. /// Similar to ParseFile. Instead it takes as argument a string.
/// </summary> /// </summary>
public BoolExpr[] ParseString(string s)
public BoolExpr[] ParseString(string s) { {
return ToBoolExprs(new ASTVector(Context, Native.Z3_fixedpoint_from_string(Context.nCtx, NativeObject, s))); ASTVector av = new ASTVector(Context, Native.Z3_fixedpoint_from_string(Context.nCtx, NativeObject, s));
return av.ToBoolExprArray();
} }

View file

@ -47,7 +47,7 @@ namespace Microsoft.Z3
/// <remarks>For more information on interpolation please refer /// <remarks>For more information on interpolation please refer
/// too the function Z3_get_interpolant in the C/C++ API, which is /// too the function Z3_get_interpolant in the C/C++ API, which is
/// well documented.</remarks> /// well documented.</remarks>
public Expr[] GetInterpolant(Expr pf, Expr pat, Params p) public BoolExpr[] GetInterpolant(Expr pf, Expr pat, Params p)
{ {
Contract.Requires(pf != null); Contract.Requires(pf != null);
Contract.Requires(pat != null); Contract.Requires(pat != null);
@ -59,11 +59,7 @@ namespace Microsoft.Z3
CheckContextMatch(p); CheckContextMatch(p);
ASTVector seq = new ASTVector(this, Native.Z3_get_interpolant(nCtx, pf.NativeObject, pat.NativeObject, p.NativeObject)); ASTVector seq = new ASTVector(this, Native.Z3_get_interpolant(nCtx, pf.NativeObject, pat.NativeObject, p.NativeObject));
uint n = seq.Size; return seq.ToBoolExprArray();
Expr[] res = new Expr[n];
for (uint i = 0; i < n; i++)
res[i] = Expr.Create(this, seq[i].NativeObject);
return res;
} }
/// <summary> /// <summary>
@ -72,7 +68,7 @@ namespace Microsoft.Z3
/// <remarks>For more information on interpolation please refer /// <remarks>For more information on interpolation please refer
/// too the function Z3_compute_interpolant in the C/C++ API, which is /// too the function Z3_compute_interpolant in the C/C++ API, which is
/// well documented.</remarks> /// well documented.</remarks>
public Z3_lbool ComputeInterpolant(Expr pat, Params p, out ASTVector interp, out Model model) public Z3_lbool ComputeInterpolant(Expr pat, Params p, out BoolExpr[] interp, out Model model)
{ {
Contract.Requires(pat != null); Contract.Requires(pat != null);
Contract.Requires(p != null); Contract.Requires(p != null);
@ -84,7 +80,7 @@ namespace Microsoft.Z3
IntPtr i = IntPtr.Zero, m = IntPtr.Zero; IntPtr i = IntPtr.Zero, m = IntPtr.Zero;
int r = Native.Z3_compute_interpolant(nCtx, pat.NativeObject, p.NativeObject, ref i, ref m); int r = Native.Z3_compute_interpolant(nCtx, pat.NativeObject, p.NativeObject, ref i, ref m);
interp = new ASTVector(this, i); interp = new ASTVector(this, i).ToBoolExprArray();
model = new Model(this, m); model = new Model(this, m);
return (Z3_lbool)r; return (Z3_lbool)r;
} }
@ -106,7 +102,7 @@ namespace Microsoft.Z3
/// <remarks>For more information on interpolation please refer /// <remarks>For more information on interpolation please refer
/// too the function Z3_check_interpolant in the C/C++ API, which is /// too the function Z3_check_interpolant in the C/C++ API, which is
/// well documented.</remarks> /// well documented.</remarks>
public int CheckInterpolant(Expr[] cnsts, uint[] parents, Expr[] interps, out string error, Expr[] theory) public int CheckInterpolant(Expr[] cnsts, uint[] parents, BoolExpr[] interps, out string error, Expr[] theory)
{ {
Contract.Requires(cnsts.Length == parents.Length); Contract.Requires(cnsts.Length == parents.Length);
Contract.Requires(cnsts.Length == interps.Length + 1); Contract.Requires(cnsts.Length == interps.Length + 1);

View file

@ -265,12 +265,8 @@ namespace Microsoft.Z3
Contract.Requires(s != null); Contract.Requires(s != null);
Contract.Ensures(Contract.Result<Expr[]>() != null); Contract.Ensures(Contract.Result<Expr[]>() != null);
ASTVector nUniv = new ASTVector(Context, Native.Z3_model_get_sort_universe(Context.nCtx, NativeObject, s.NativeObject)); ASTVector av = new ASTVector(Context, Native.Z3_model_get_sort_universe(Context.nCtx, NativeObject, s.NativeObject));
uint n = nUniv.Size; return av.ToExprArray();
Expr[] res = new Expr[n];
for (uint i = 0; i < n; i++)
res[i] = Expr.Create(Context, nUniv[i].NativeObject);
return res;
} }
/// <summary> /// <summary>

View file

@ -178,8 +178,8 @@ namespace Microsoft.Z3
{ {
get get
{ {
ASTVector ass = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject)); ASTVector assertions = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
return ass.Size; return assertions.Size;
} }
} }
@ -192,12 +192,8 @@ namespace Microsoft.Z3
{ {
Contract.Ensures(Contract.Result<BoolExpr[]>() != null); Contract.Ensures(Contract.Result<BoolExpr[]>() != null);
ASTVector ass = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject)); ASTVector assertions = new ASTVector(Context, Native.Z3_solver_get_assertions(Context.nCtx, NativeObject));
uint n = ass.Size; return assertions.ToBoolExprArray();
BoolExpr[] res = new BoolExpr[n];
for (uint i = 0; i < n; i++)
res[i] = new BoolExpr(Context, ass[i].NativeObject);
return res;
} }
} }
@ -270,18 +266,14 @@ namespace Microsoft.Z3
/// The result is empty if <c>Check</c> was not invoked before, /// The result is empty if <c>Check</c> was not invoked before,
/// if its results was not <c>UNSATISFIABLE</c>, or if core production is disabled. /// if its results was not <c>UNSATISFIABLE</c>, or if core production is disabled.
/// </remarks> /// </remarks>
public Expr[] UnsatCore public BoolExpr[] UnsatCore
{ {
get get
{ {
Contract.Ensures(Contract.Result<Expr[]>() != null); Contract.Ensures(Contract.Result<Expr[]>() != null);
ASTVector core = new ASTVector(Context, Native.Z3_solver_get_unsat_core(Context.nCtx, NativeObject)); ASTVector core = new ASTVector(Context, Native.Z3_solver_get_unsat_core(Context.nCtx, NativeObject));
uint n = core.Size; return core.ToBoolExprArray();
Expr[] res = new Expr[n];
for (uint i = 0; i < n; i++)
res[i] = Expr.Create(Context, core[i].NativeObject);
return res;
} }
} }

View file

@ -92,10 +92,10 @@ class ASTMap extends Z3Object
* *
* @throws Z3Exception * @throws Z3Exception
**/ **/
public ASTVector getKeys() public AST[] getKeys()
{ {
return new ASTVector(getContext(), Native.astMapKeys(getContext().nCtx(), ASTVector av = new ASTVector(getContext(), Native.astMapKeys(getContext().nCtx(), getNativeObject()));
getNativeObject())); return av.ToArray();
} }
/** /**

View file

@ -119,4 +119,135 @@ public class ASTVector extends Z3Object
getContext().getASTVectorDRQ().add(o); getContext().getASTVectorDRQ().add(o);
super.decRef(o); super.decRef(o);
} }
}
/**
* Translates the AST vector into an AST[]
* */
public AST[] ToArray()
{
int n = size();
AST[] res = new AST[n];
for (int i = 0; i < n; i++)
res[i] = AST.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an Expr[]
* */
public Expr[] ToExprArray() {
int n = size();
Expr[] res = new Expr[n];
for (int i = 0; i < n; i++)
res[i] = Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an BoolExpr[]
* */
public BoolExpr[] ToBoolExprArray()
{
int n = size();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = (BoolExpr) Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an BitVecExpr[]
* */
public BitVecExpr[] ToBitVecExprArray()
{
int n = size();
BitVecExpr[] res = new BitVecExpr[n];
for (int i = 0; i < n; i++)
res[i] = (BitVecExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an ArithExpr[]
* */
public ArithExpr[] ToArithExprExprArray()
{
int n = size();
ArithExpr[] res = new ArithExpr[n];
for (int i = 0; i < n; i++)
res[i] = (ArithExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an ArrayExpr[]
* */
public ArrayExpr[] ToArrayExprArray()
{
int n = size();
ArrayExpr[] res = new ArrayExpr[n];
for (int i = 0; i < n; i++)
res[i] = (ArrayExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an DatatypeExpr[]
* */
public DatatypeExpr[] ToDatatypeExprArray()
{
int n = size();
DatatypeExpr[] res = new DatatypeExpr[n];
for (int i = 0; i < n; i++)
res[i] = (DatatypeExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an FPExpr[]
* */
public FPExpr[] ToFPExprArray()
{
int n = size();
FPExpr[] res = new FPExpr[n];
for (int i = 0; i < n; i++)
res[i] = (FPExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an FPRMExpr[]
* */
public FPRMExpr[] ToFPRMExprArray()
{
int n = size();
FPRMExpr[] res = new FPRMExpr[n];
for (int i = 0; i < n; i++)
res[i] = (FPRMExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an IntExpr[]
* */
public IntExpr[] ToIntExprArray()
{
int n = size();
IntExpr[] res = new IntExpr[n];
for (int i = 0; i < n; i++)
res[i] = (IntExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
/**
* Translates the AST vector into an RealExpr[]
* */
public RealExpr[] ToRealExprArray()
{
int n = size();
RealExpr[] res = new RealExpr[n];
for (int i = 0; i < n; i++)
res[i] = (RealExpr)Expr.create(getContext(), get(i).getNativeObject());
return res;
}
}

View file

@ -295,14 +295,8 @@ public class Fixedpoint extends Z3Object
**/ **/
public BoolExpr[] getRules() public BoolExpr[] getRules()
{ {
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetRules(getContext().nCtx(), getNativeObject()));
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetRules( return v.ToBoolExprArray();
getContext().nCtx(), getNativeObject()));
int n = v.size();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = new BoolExpr(getContext(), v.get(i).getNativeObject());
return res;
} }
/** /**
@ -312,14 +306,8 @@ public class Fixedpoint extends Z3Object
**/ **/
public BoolExpr[] getAssertions() public BoolExpr[] getAssertions()
{ {
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetAssertions(getContext().nCtx(), getNativeObject()));
ASTVector v = new ASTVector(getContext(), Native.fixedpointGetAssertions( return v.ToBoolExprArray();
getContext().nCtx(), getNativeObject()));
int n = v.size();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = new BoolExpr(getContext(), v.get(i).getNativeObject());
return res;
} }
/** /**
@ -327,12 +315,34 @@ public class Fixedpoint extends Z3Object
* *
* @throws Z3Exception * @throws Z3Exception
**/ **/
public Statistics getStatistics() throws Z3Exception public Statistics getStatistics()
{ {
return new Statistics(getContext(), Native.fixedpointGetStatistics( return new Statistics(getContext(), Native.fixedpointGetStatistics(
getContext().nCtx(), getNativeObject())); getContext().nCtx(), getNativeObject()));
} }
/**
* Parse an SMT-LIB2 file with fixedpoint rules.
* Add the rules to the current fixedpoint context.
* Return the set of queries in the file.
**/
public BoolExpr[] ParseFile(String file)
{
ASTVector av = new ASTVector(getContext(), Native.fixedpointFromFile(getContext().nCtx(), getNativeObject(), file));
return av.ToBoolExprArray();
}
/**
* Parse an SMT-LIB2 string with fixedpoint rules.
* Add the rules to the current fixedpoint context.
* Return the set of queries in the file.
**/
public BoolExpr[] ParseString(String s)
{
ASTVector av = new ASTVector(getContext(), Native.fixedpointFromString(getContext().nCtx(), getNativeObject(), s));
return av.ToBoolExprArray();
}
Fixedpoint(Context ctx, long obj) throws Z3Exception Fixedpoint(Context ctx, long obj) throws Z3Exception
{ {

View file

@ -73,18 +73,14 @@ public class InterpolationContext extends Context
* well documented. * well documented.
* @throws Z3Exception * @throws Z3Exception
**/ **/
public Expr[] GetInterpolant(Expr pf, Expr pat, Params p) public BoolExpr[] GetInterpolant(Expr pf, Expr pat, Params p)
{ {
checkContextMatch(pf); checkContextMatch(pf);
checkContextMatch(pat); checkContextMatch(pat);
checkContextMatch(p); checkContextMatch(p);
ASTVector seq = new ASTVector(this, Native.getInterpolant(nCtx(), pf.getNativeObject(), pat.getNativeObject(), p.getNativeObject())); ASTVector seq = new ASTVector(this, Native.getInterpolant(nCtx(), pf.getNativeObject(), pat.getNativeObject(), p.getNativeObject()));
int n = seq.size(); return seq.ToBoolExprArray();
Expr[] res = new Expr[n];
for (int i = 0; i < n; i++)
res[i] = Expr.create(this, seq.get(i).getNativeObject());
return res;
} }
public class ComputeInterpolantResult public class ComputeInterpolantResult
@ -110,13 +106,10 @@ public class InterpolationContext extends Context
Native.LongPtr n_i = new Native.LongPtr(); Native.LongPtr n_i = new Native.LongPtr();
Native.LongPtr n_m = new Native.LongPtr(); Native.LongPtr n_m = new Native.LongPtr();
res.status = Z3_lbool.fromInt(Native.computeInterpolant(nCtx(), pat.getNativeObject(), p.getNativeObject(), n_i, n_m)); res.status = Z3_lbool.fromInt(Native.computeInterpolant(nCtx(), pat.getNativeObject(), p.getNativeObject(), n_i, n_m));
if (res.status == Z3_lbool.Z3_L_FALSE) {xx if (res.status == Z3_lbool.Z3_L_FALSE)
res.interp = new BoolExpr[Native.astVectorSize(nCtx(), n_i.value)]; res.interp = (new ASTVector(this, n_i.value)).ToBoolExprArray();
for (int i = 0; i < res.interp.Length; ++i) { if (res.status == Z3_lbool.Z3_L_TRUE)
res.interp[i] = new BoolExpr(this, Native.astVectorGet(nCtx(), i)); res.model = new Model(this, n_m.value);
}
}
if (res.status == Z3_lbool.Z3_L_TRUE) res.model = new Model(this, n_m.value);
return res; return res;
} }
@ -143,7 +136,7 @@ public class InterpolationContext extends Context
/// Remarks: For more information on interpolation please refer /// Remarks: For more information on interpolation please refer
/// too the function Z3_check_interpolant in the C/C++ API, which is /// too the function Z3_check_interpolant in the C/C++ API, which is
/// well documented. /// well documented.
public CheckInterpolantResult CheckInterpolant(Expr[] cnsts, int[] parents, Expr[] interps, String error, Expr[] theory) public CheckInterpolantResult CheckInterpolant(Expr[] cnsts, int[] parents, BoolExpr[] interps, String error, Expr[] theory)
{ {
CheckInterpolantResult res = new CheckInterpolantResult(); CheckInterpolantResult res = new CheckInterpolantResult();
Native.StringPtr n_err_str = new Native.StringPtr(); Native.StringPtr n_err_str = new Native.StringPtr();

View file

@ -273,11 +273,7 @@ public class Model extends Z3Object
ASTVector nUniv = new ASTVector(getContext(), Native.modelGetSortUniverse( ASTVector nUniv = new ASTVector(getContext(), Native.modelGetSortUniverse(
getContext().nCtx(), getNativeObject(), s.getNativeObject())); getContext().nCtx(), getNativeObject(), s.getNativeObject()));
int n = nUniv.size(); return nUniv.ToExprArray();
Expr[] res = new Expr[n];
for (int i = 0; i < n; i++)
res[i] = Expr.create(getContext(), nUniv.get(i).getNativeObject());
return res;
} }
/** /**

View file

@ -176,8 +176,7 @@ public class Solver extends Z3Object
**/ **/
public int getNumAssertions() public int getNumAssertions()
{ {
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions( ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(getContext().nCtx(), getNativeObject()));
getContext().nCtx(), getNativeObject()));
return assrts.size(); return assrts.size();
} }
@ -188,13 +187,8 @@ public class Solver extends Z3Object
**/ **/
public BoolExpr[] getAssertions() public BoolExpr[] getAssertions()
{ {
ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions( ASTVector assrts = new ASTVector(getContext(), Native.solverGetAssertions(getContext().nCtx(), getNativeObject()));
getContext().nCtx(), getNativeObject())); return assrts.ToBoolExprArray();
int n = assrts.size();
BoolExpr[] res = new BoolExpr[n];
for (int i = 0; i < n; i++)
res[i] = new BoolExpr(getContext(), assrts.get(i).getNativeObject());
return res;
} }
/** /**
@ -282,16 +276,11 @@ public class Solver extends Z3Object
* *
* @throws Z3Exception * @throws Z3Exception
**/ **/
public Expr[] getUnsatCore() public BoolExpr[] getUnsatCore()
{ {
ASTVector core = new ASTVector(getContext(), Native.solverGetUnsatCore( ASTVector core = new ASTVector(getContext(), Native.solverGetUnsatCore(getContext().nCtx(), getNativeObject()));
getContext().nCtx(), getNativeObject())); return core.ToBoolExprArray();
int n = core.size();
Expr[] res = new Expr[n];
for (int i = 0; i < n; i++)
res[i] = Expr.create(getContext(), core.get(i).getNativeObject());
return res;
} }
/** /**

File diff suppressed because it is too large Load diff

View file

@ -123,7 +123,7 @@ sig
end end
(** The abstract syntax tree (AST) module *) (** The abstract syntax tree (AST) module *)
module AST : module rec AST :
sig sig
type ast type ast
@ -156,6 +156,12 @@ sig
@return A new ASTVector *) @return A new ASTVector *)
val translate : ast_vector -> context -> ast_vector val translate : ast_vector -> context -> ast_vector
(** Translates the ASTVector into an (Ast.ast list) *)
val to_list : ast_vector -> ast list
(** Translates the ASTVector into an (Expr.expr list) *)
val to_expr_list : ast_vector -> Expr.expr list
(** Retrieves a string representation of the vector. *) (** Retrieves a string representation of the vector. *)
val to_string : ast_vector -> string val to_string : ast_vector -> string
end end
@ -189,7 +195,7 @@ sig
val get_size : ast_map -> int val get_size : ast_map -> int
(** The keys stored in the map. *) (** The keys stored in the map. *)
val get_keys : ast_map -> ast list val get_keys : ast_map -> Expr.expr list
(** Retrieves a string representation of the map.*) (** Retrieves a string representation of the map.*)
val to_string : ast_map -> string val to_string : ast_map -> string
@ -260,7 +266,7 @@ sig
end end
(** The Sort module implements type information for ASTs *) (** The Sort module implements type information for ASTs *)
module Sort : and Sort :
sig sig
type sort = Sort of AST.ast type sort = Sort of AST.ast
@ -291,7 +297,7 @@ sig
end end
(** Function declarations *) (** Function declarations *)
module rec FuncDecl : and FuncDecl :
sig sig
type func_decl = FuncDecl of AST.ast type func_decl = FuncDecl of AST.ast
@ -2751,7 +2757,7 @@ sig
(** The finite set of distinct values that represent the interpretation of a sort. (** The finite set of distinct values that represent the interpretation of a sort.
{!get_sorts} {!get_sorts}
@return A list of expressions, where each is an element of the universe of the sort *) @return A list of expressions, where each is an element of the universe of the sort *)
val sort_universe : model -> Sort.sort -> AST.ast list val sort_universe : model -> Sort.sort -> Expr.expr list
(** Conversion of models to strings. (** Conversion of models to strings.
@return A string representation of the model. *) @return A string representation of the model. *)
@ -2938,6 +2944,55 @@ sig
val interrupt : context -> unit val interrupt : context -> unit
end end
(** Objects that track statistical information. *)
module Statistics :
sig
type statistics
(** Statistical data is organized into pairs of \[Key, Entry\], where every
Entry is either a floating point or integer value. *)
module Entry :
sig
type statistics_entry
(** The key of the entry. *)
val get_key : statistics_entry -> string
(** The int-value of the entry. *)
val get_int : statistics_entry -> int
(** The float-value of the entry. *)
val get_float : statistics_entry -> float
(** True if the entry is uint-valued. *)
val is_int : statistics_entry -> bool
(** True if the entry is float-valued. *)
val is_float : statistics_entry -> bool
(** The string representation of the the entry's value. *)
val to_string_value : statistics_entry -> string
(** The string representation of the entry (key and value) *)
val to_string : statistics_entry -> string
end
(** A string representation of the statistical data. *)
val to_string : statistics -> string
(** The number of statistical data. *)
val get_size : statistics -> int
(** The data entries. *)
val get_entries : statistics -> Entry.statistics_entry list
(** The statistical counters. *)
val get_keys : statistics -> string list
(** The value of a particular statistical counter. *)
val get : statistics -> string -> Entry.statistics_entry option
end
(** Solvers *) (** Solvers *)
module Solver : module Solver :
sig sig
@ -2946,56 +3001,6 @@ sig
val string_of_status : status -> string val string_of_status : status -> string
(** Objects that track statistical information about solvers. *)
module Statistics :
sig
type statistics
(** Statistical data is organized into pairs of \[Key, Entry\], where every
Entry is either a floating point or integer value.
*)
module Entry :
sig
type statistics_entry
(** The key of the entry. *)
val get_key : statistics_entry -> string
(** The int-value of the entry. *)
val get_int : statistics_entry -> int
(** The float-value of the entry. *)
val get_float : statistics_entry -> float
(** True if the entry is uint-valued. *)
val is_int : statistics_entry -> bool
(** True if the entry is float-valued. *)
val is_float : statistics_entry -> bool
(** The string representation of the the entry's value. *)
val to_string_value : statistics_entry -> string
(** The string representation of the entry (key and value) *)
val to_string : statistics_entry -> string
end
(** A string representation of the statistical data. *)
val to_string : statistics -> string
(** The number of statistical data. *)
val get_size : statistics -> int
(** The data entries. *)
val get_entries : statistics -> Entry.statistics_entry list
(** The statistical counters. *)
val get_keys : statistics -> string list
(** The value of a particular statistical counter. *)
val get : statistics -> string -> Entry.statistics_entry option
end
(** A string that describes all available solver parameters. *) (** A string that describes all available solver parameters. *)
val get_help : solver -> string val get_help : solver -> string
@ -3081,7 +3086,7 @@ sig
The unsat core is a subset of [Assertions] The unsat core is a subset of [Assertions]
The result is empty if [Check] was not invoked before, The result is empty if [Check] was not invoked before,
if its results was not [UNSATISFIABLE], or if core production is disabled. *) if its results was not [UNSATISFIABLE], or if core production is disabled. *)
val get_unsat_core : solver -> AST.ast list val get_unsat_core : solver -> Expr.expr list
(** A brief justification of why the last call to [Check] returned [UNKNOWN]. *) (** A brief justification of why the last call to [Check] returned [UNKNOWN]. *)
val get_reason_unknown : solver -> string val get_reason_unknown : solver -> string
@ -3198,6 +3203,19 @@ sig
(** Create a Fixedpoint context. *) (** Create a Fixedpoint context. *)
val mk_fixedpoint : context -> fixedpoint val mk_fixedpoint : context -> fixedpoint
(** Retrieve statistics information from the last call to #Z3_fixedpoint_query. *)
val get_statistics : fixedpoint -> Statistics.statistics
(** Parse an SMT-LIB2 string with fixedpoint rules.
Add the rules to the current fixedpoint context.
Return the set of queries in the string. *)
val parse_string : fixedpoint -> string -> Expr.expr list
(** Parse an SMT-LIB2 file with fixedpoint rules.
Add the rules to the current fixedpoint context.
Return the set of queries in the file. *)
val parse_file : fixedpoint -> string -> Expr.expr list
end end
(** Functions for handling SMT and SMT2 expressions and files *) (** Functions for handling SMT and SMT2 expressions and files *)
@ -3272,12 +3290,12 @@ sig
(** Gets an interpolant. (** Gets an interpolant.
For more information on interpolation please refer For more information on interpolation please refer
too the C/C++ API, which is well documented. *) too the C/C++ API, which is well documented. *)
val get_interpolant : context -> Expr.expr -> Expr.expr -> Params.params -> AST.ASTVector.ast_vector val get_interpolant : context -> Expr.expr -> Expr.expr -> Params.params -> Expr.expr list
(** Computes an interpolant. (** Computes an interpolant.
For more information on interpolation please refer For more information on interpolation please refer
too the C/C++ API, which is well documented. *) too the C/C++ API, which is well documented. *)
val compute_interpolant : context -> Expr.expr -> Params.params -> (AST.ASTVector.ast_vector * Model.model) val compute_interpolant : context -> Expr.expr -> Params.params -> (Z3enums.lbool * Expr.expr list option * Model.model option)
(** Retrieves an interpolation profile. (** Retrieves an interpolation profile.
For more information on interpolation please refer For more information on interpolation please refer

View file

@ -6022,7 +6022,7 @@ END_MLAPI_EXCLUDE
/** /**
\brief Parse an SMT-LIB2 string with fixedpoint rules. \brief Parse an SMT-LIB2 string with fixedpoint rules.
Add the rules to the current fixedpoint context. Add the rules to the current fixedpoint context.
Return the set of queries in the file. Return the set of queries in the string.
\param c - context. \param c - context.
\param f - fixedpoint context. \param f - fixedpoint context.

View file

@ -316,7 +316,8 @@ func_decl::func_decl(symbol const & name, unsigned arity, sort * const * domain,
decl(AST_FUNC_DECL, name, info), decl(AST_FUNC_DECL, name, info),
m_arity(arity), m_arity(arity),
m_range(range) { m_range(range) {
memcpy(const_cast<sort **>(get_domain()), domain, sizeof(sort *) * arity); if (arity != 0)
memcpy(const_cast<sort **>(get_domain()), domain, sizeof(sort *) * arity);
} }
// ----------------------------------- // -----------------------------------
@ -378,8 +379,10 @@ quantifier::quantifier(bool forall, unsigned num_decls, sort * const * decl_sort
memcpy(const_cast<sort **>(get_decl_sorts()), decl_sorts, sizeof(sort *) * num_decls); memcpy(const_cast<sort **>(get_decl_sorts()), decl_sorts, sizeof(sort *) * num_decls);
memcpy(const_cast<symbol*>(get_decl_names()), decl_names, sizeof(symbol) * num_decls); memcpy(const_cast<symbol*>(get_decl_names()), decl_names, sizeof(symbol) * num_decls);
memcpy(const_cast<expr **>(get_patterns()), patterns, sizeof(expr *) * num_patterns); if (num_patterns != 0)
memcpy(const_cast<expr **>(get_no_patterns()), no_patterns, sizeof(expr *) * num_no_patterns); memcpy(const_cast<expr **>(get_patterns()), patterns, sizeof(expr *) * num_patterns);
if (num_no_patterns != 0)
memcpy(const_cast<expr **>(get_no_patterns()), no_patterns, sizeof(expr *) * num_no_patterns);
} }
// ----------------------------------- // -----------------------------------

View file

@ -48,19 +48,31 @@ void fpa2bv_converter::mk_eq(expr * a, expr * b, expr_ref & result) {
SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_FP)); SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_FP));
SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_FP)); SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_FP));
expr_ref sgn(m), s(m), e(m); TRACE("fpa2bv", tout << "mk_eq a=" << mk_ismt2_pp(a, m) << std::endl;
m_simp.mk_eq(to_app(a)->get_arg(0), to_app(b)->get_arg(0), sgn); tout << "mk_eq b=" << mk_ismt2_pp(b, m) << std::endl;);
m_simp.mk_eq(to_app(a)->get_arg(1), to_app(b)->get_arg(1), e);
m_simp.mk_eq(to_app(a)->get_arg(2), to_app(b)->get_arg(2), s); expr_ref eq_sgn(m), eq_exp(m), eq_sig(m);
m_simp.mk_eq(to_app(a)->get_arg(0), to_app(b)->get_arg(0), eq_sgn);
m_simp.mk_eq(to_app(a)->get_arg(1), to_app(b)->get_arg(1), eq_exp);
m_simp.mk_eq(to_app(a)->get_arg(2), to_app(b)->get_arg(2), eq_sig);
dbg_decouple("fpa2bv_eq_sgn", eq_sgn);
dbg_decouple("fpa2bv_eq_exp", eq_exp);
dbg_decouple("fpa2bv_eq_sig", eq_sig);
expr_ref both_the_same(m);
m_simp.mk_and(eq_sgn, eq_exp, eq_sig, both_the_same);
dbg_decouple("fpa2bv_eq_both_the_same", both_the_same);
// The SMT FPA theory asks for _one_ NaN value, but the bit-blasting // The SMT FPA theory asks for _one_ NaN value, but the bit-blasting
// has many, like IEEE754. This encoding of equality makes it look like // has many, like IEEE754. This encoding of equality makes it look like
// a single NaN again. // a single NaN again.
expr_ref both_the_same(m), a_is_nan(m), b_is_nan(m), both_are_nan(m); expr_ref a_is_nan(m), b_is_nan(m), both_are_nan(m);
m_simp.mk_and(sgn, s, e, both_the_same);
mk_is_nan(a, a_is_nan); mk_is_nan(a, a_is_nan);
mk_is_nan(b, b_is_nan); mk_is_nan(b, b_is_nan);
m_simp.mk_and(a_is_nan, b_is_nan, both_are_nan); m_simp.mk_and(a_is_nan, b_is_nan, both_are_nan);
dbg_decouple("fpa2bv_eq_both_are_nan", both_are_nan);
m_simp.mk_or(both_are_nan, both_the_same, result); m_simp.mk_or(both_are_nan, both_the_same, result);
} }
@ -2051,6 +2063,7 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr *
expr_ref sgn(m), sig(m), exp(m), lz(m); expr_ref sgn(m), sig(m), exp(m), lz(m);
unpack(x, sgn, sig, exp, lz, true); unpack(x, sgn, sig, exp, lz, true);
dbg_decouple("fpa2bv_to_float_x_sgn", sgn);
dbg_decouple("fpa2bv_to_float_x_sig", sig); dbg_decouple("fpa2bv_to_float_x_sig", sig);
dbg_decouple("fpa2bv_to_float_x_exp", exp); dbg_decouple("fpa2bv_to_float_x_exp", exp);
dbg_decouple("fpa2bv_to_float_lz", lz); dbg_decouple("fpa2bv_to_float_lz", lz);
@ -2068,13 +2081,17 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr *
// make sure that sig has at least to_sbits + 3 // make sure that sig has at least to_sbits + 3
res_sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, to_sbits + 3 - from_sbits)); res_sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, to_sbits + 3 - from_sbits));
} }
else if (from_sbits >(to_sbits + 3)) { else if (from_sbits > (to_sbits + 3)) {
// collapse the extra bits into a sticky bit. // collapse the extra bits into a sticky bit.
expr_ref sticky(m), low(m), high(m); expr_ref sticky(m), low(m), high(m);
low = m_bv_util.mk_extract(from_sbits - to_sbits - 3, 0, sig);
high = m_bv_util.mk_extract(from_sbits - 1, from_sbits - to_sbits - 2, sig); high = m_bv_util.mk_extract(from_sbits - 1, from_sbits - to_sbits - 2, sig);
SASSERT(m_bv_util.get_bv_size(high) == to_sbits + 2);
low = m_bv_util.mk_extract(from_sbits - to_sbits - 3, 0, sig);
sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, low.get()); sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, low.get());
res_sig = m_bv_util.mk_concat(high, sticky); SASSERT(m_bv_util.get_bv_size(sticky) == 1);
dbg_decouple("fpa2bv_to_float_sticky", sticky);
res_sig = m_bv_util.mk_concat(high, sticky);
SASSERT(m_bv_util.get_bv_size(res_sig) == to_sbits + 3);
} }
else else
res_sig = sig; res_sig = sig;
@ -2083,8 +2100,9 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr *
unsigned sig_sz = m_bv_util.get_bv_size(res_sig); unsigned sig_sz = m_bv_util.get_bv_size(res_sig);
SASSERT(sig_sz == to_sbits + 4); SASSERT(sig_sz == to_sbits + 4);
expr_ref exponent_overflow(m); expr_ref exponent_overflow(m), exponent_underflow(m);
exponent_overflow = m.mk_false(); exponent_overflow = m.mk_false();
exponent_underflow = m.mk_false();
if (from_ebits < (to_ebits + 2)) { if (from_ebits < (to_ebits + 2)) {
res_exp = m_bv_util.mk_sign_extend(to_ebits - from_ebits + 2, exp); res_exp = m_bv_util.mk_sign_extend(to_ebits - from_ebits + 2, exp);
@ -2094,37 +2112,58 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr *
lz_ext = m_bv_util.mk_zero_extend(to_ebits - from_ebits + 2, lz); lz_ext = m_bv_util.mk_zero_extend(to_ebits - from_ebits + 2, lz);
res_exp = m_bv_util.mk_bv_sub(res_exp, lz_ext); res_exp = m_bv_util.mk_bv_sub(res_exp, lz_ext);
} }
else if (from_ebits >(to_ebits + 2)) { else if (from_ebits > (to_ebits + 2)) {
expr_ref high(m), low(m), lows(m), high_red_or(m), high_red_and(m), h_or_eq(m), h_and_eq(m); expr_ref lz_rest(m), lz_redor(m), lz_redor_bool(m);
expr_ref no_ovf(m), zero1(m), s_is_one(m), s_is_zero(m);
high = m_bv_util.mk_extract(from_ebits - 1, to_ebits + 2, exp);
low = m_bv_util.mk_extract(to_ebits + 1, 0, exp);
lows = m_bv_util.mk_extract(to_ebits + 1, to_ebits + 1, low);
high_red_or = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, high.get());
high_red_and = m.mk_app(m_bv_util.get_fid(), OP_BREDAND, high.get());
zero1 = m_bv_util.mk_numeral(0, 1);
m_simp.mk_eq(high_red_and, one1, h_and_eq);
m_simp.mk_eq(high_red_or, zero1, h_or_eq);
m_simp.mk_eq(lows, zero1, s_is_zero);
m_simp.mk_eq(lows, one1, s_is_one);
expr_ref c2(m);
m_simp.mk_ite(h_or_eq, s_is_one, m.mk_false(), c2);
m_simp.mk_ite(h_and_eq, s_is_zero, c2, exponent_overflow);
// Note: Upon overflow, we _could_ try to shift the significand around...
// subtract lz for subnormal numbers.
expr_ref lz_ext(m), lz_rest(m), lz_redor(m), lz_redor_bool(m);
lz_ext = m_bv_util.mk_extract(to_ebits + 1, 0, lz);
lz_rest = m_bv_util.mk_extract(from_ebits - 1, to_ebits + 2, lz); lz_rest = m_bv_util.mk_extract(from_ebits - 1, to_ebits + 2, lz);
lz_redor = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, lz_rest.get()); lz_redor = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, lz_rest.get());
m_simp.mk_eq(lz_redor, one1, lz_redor_bool); m_simp.mk_eq(lz_redor, one1, lz_redor_bool);
m_simp.mk_or(exponent_overflow, lz_redor_bool, exponent_overflow); dbg_decouple("fpa2bv_to_float_exp_lz_redor", lz_redor);
res_exp = m_bv_util.mk_bv_sub(low, lz_ext); // subtract lz for subnormal numbers.
expr_ref exp_sub_lz(m);
exp_sub_lz = m_bv_util.mk_bv_sub(exp, lz);
dbg_decouple("fpa2bv_to_float_exp_sub_lz", exp_sub_lz);
expr_ref high(m), low(m), low_msb(m);
expr_ref no_ovf(m), zero1(m);
high = m_bv_util.mk_extract(from_ebits - 1, to_ebits + 2, exp_sub_lz);
low = m_bv_util.mk_extract(to_ebits + 1, 0, exp_sub_lz);
low_msb = m_bv_util.mk_extract(to_ebits + 1, to_ebits + 1, low);
dbg_decouple("fpa2bv_to_float_exp_high", high);
dbg_decouple("fpa2bv_to_float_exp_low", low);
dbg_decouple("fpa2bv_to_float_exp_low_msb", low_msb);
res_exp = low;
expr_ref high_red_or(m), high_red_and(m);
high_red_or = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, high.get());
high_red_and = m.mk_app(m_bv_util.get_fid(), OP_BREDAND, high.get());
expr_ref h_or_eq_0(m), h_and_eq_1(m), low_msb_is_one(m), low_msb_is_zero(m);
zero1 = m_bv_util.mk_numeral(0, 1);
m_simp.mk_eq(high_red_and, one1, h_and_eq_1);
m_simp.mk_eq(high_red_or, zero1, h_or_eq_0);
m_simp.mk_eq(low_msb, zero1, low_msb_is_zero);
m_simp.mk_eq(low_msb, one1, low_msb_is_one);
dbg_decouple("fpa2bv_to_float_exp_h_and_eq_1", h_and_eq_1);
dbg_decouple("fpa2bv_to_float_exp_h_or_eq_0", h_or_eq_0);
dbg_decouple("fpa2bv_to_float_exp_s_is_zero", low_msb_is_zero);
dbg_decouple("fpa2bv_to_float_exp_s_is_one", low_msb_is_one);
m_simp.mk_and(h_or_eq_0, low_msb_is_one, exponent_underflow);
m_simp.mk_and(h_and_eq_1, low_msb_is_zero, exponent_overflow);
m_simp.mk_or(exponent_overflow, lz_redor_bool, exponent_overflow);
dbg_decouple("fpa2bv_to_float_exp_ovf", exponent_overflow);
dbg_decouple("fpa2bv_to_float_exp_udf", exponent_underflow);
// exponent underflow means that the result is the smallest
// representable float, rounded according to rm.
m_simp.mk_ite(exponent_underflow,
m_bv_util.mk_concat(m_bv_util.mk_numeral(1, 1),
m_bv_util.mk_numeral(1, to_ebits+1)),
res_exp,
res_exp);
m_simp.mk_ite(exponent_underflow, m_bv_util.mk_numeral(1, to_sbits+4), res_sig, res_sig);
} }
else // from_ebits == (to_ebits + 2) else // from_ebits == (to_ebits + 2)
res_exp = m_bv_util.mk_bv_sub(exp, lz); res_exp = m_bv_util.mk_bv_sub(exp, lz);
@ -2143,8 +2182,7 @@ void fpa2bv_converter::mk_to_fp_float(func_decl * f, sort * s, expr * rm, expr *
m_simp.mk_eq(sgn, one1, is_neg); m_simp.mk_eq(sgn, one1, is_neg);
mk_ite(is_neg, ninf, pinf, sig_inf); mk_ite(is_neg, ninf, pinf, sig_inf);
dbg_decouple("fpa2bv_to_float_exp_ovf", exponent_overflow); mk_ite(exponent_overflow, sig_inf, rounded, v6);
mk_ite(exponent_overflow, sig_inf, rounded, v6);
// And finally, we tie them together. // And finally, we tie them together.
mk_ite(c5, v5, v6, result); mk_ite(c5, v5, v6, result);
@ -3044,13 +3082,6 @@ void fpa2bv_converter::mk_is_nan(expr * e, expr_ref & result) {
m_simp.mk_not(sig_is_zero, sig_is_not_zero); m_simp.mk_not(sig_is_zero, sig_is_not_zero);
m_simp.mk_eq(exp, top_exp, exp_is_top); m_simp.mk_eq(exp, top_exp, exp_is_top);
m_simp.mk_and(exp_is_top, sig_is_not_zero, result); m_simp.mk_and(exp_is_top, sig_is_not_zero, result);
// Inject auxiliary lemmas that fix e to the one and only NaN value,
// that is (= e (fp #b0 #b1...1 #b0...01)), so that the value propagation
// has a value to propagate.
m_extra_assertions.push_back(m.mk_eq(sgn, m_bv_util.mk_numeral(0, 1)));
m_extra_assertions.push_back(m.mk_eq(exp, top_exp));
m_extra_assertions.push_back(m.mk_eq(sig, m_bv_util.mk_numeral(1, m_bv_util.get_bv_size(sig))));
} }
void fpa2bv_converter::mk_is_inf(expr * e, expr_ref & result) { void fpa2bv_converter::mk_is_inf(expr * e, expr_ref & result) {

View file

@ -966,7 +966,7 @@ public:
get_linear_coefficients(t,coeffs); get_linear_coefficients(t,coeffs);
if(coeffs.size() == 0) if(coeffs.size() == 0)
return make_int("1"); // arbitrary return make_int("1"); // arbitrary
rational d = coeffs[0]; rational d = abs(coeffs[0]);
for(unsigned i = 1; i < coeffs.size(); i++){ for(unsigned i = 1; i < coeffs.size(); i++){
d = gcd(d,coeffs[i]); d = gcd(d,coeffs[i]);
} }

View file

@ -542,6 +542,7 @@ namespace polynomial {
increase_capacity(sz * 2); increase_capacity(sz * 2);
SASSERT(sz < m_capacity); SASSERT(sz < m_capacity);
m_ptr->m_size = sz; m_ptr->m_size = sz;
if (sz == 0) return;
memcpy(m_ptr->m_powers, pws, sizeof(power) * sz); memcpy(m_ptr->m_powers, pws, sizeof(power) * sz);
} }

View file

@ -79,7 +79,7 @@ namespace simplex {
}; };
col_entry(int r, int i): m_row_id(r), m_row_idx(i) {} col_entry(int r, int i): m_row_id(r), m_row_idx(i) {}
col_entry(): m_row_id(0), m_row_idx(0) {} col_entry(): m_row_id(0), m_row_idx(0) {}
bool is_dead() const { return m_row_id == dead_id; } bool is_dead() const { return (unsigned) m_row_id == dead_id; }
}; };
struct column; struct column;

View file

@ -79,7 +79,7 @@ namespace simplex {
void sparse_matrix<Ext>::_row::del_row_entry(unsigned idx) { void sparse_matrix<Ext>::_row::del_row_entry(unsigned idx) {
_row_entry & t = m_entries[idx]; _row_entry & t = m_entries[idx];
SASSERT(!t.is_dead()); SASSERT(!t.is_dead());
t.m_next_free_row_entry_idx = m_first_free_idx; t.m_next_free_row_entry_idx = (unsigned)m_first_free_idx;
t.m_var = dead_id; t.m_var = dead_id;
m_size--; m_size--;
m_first_free_idx = idx; m_first_free_idx = idx;
@ -513,8 +513,8 @@ namespace simplex {
SASSERT(!m.is_zero(e.m_coeff)); SASSERT(!m.is_zero(e.m_coeff));
SASSERT(e.m_var != dead_id); SASSERT(e.m_var != dead_id);
col_entry const& c = m_columns[e.m_var].m_entries[e.m_col_idx]; col_entry const& c = m_columns[e.m_var].m_entries[e.m_col_idx];
SASSERT(c.m_row_id == row_id); SASSERT((unsigned)c.m_row_id == row_id);
SASSERT(c.m_row_idx == i); SASSERT((unsigned)c.m_row_idx == i);
vars.insert(e.m_var); vars.insert(e.m_var);
} }
int idx = r.m_first_free_idx; int idx = r.m_first_free_idx;
@ -544,7 +544,7 @@ namespace simplex {
_row const& row = m_rows[c.m_row_id]; _row const& row = m_rows[c.m_row_id];
_row_entry const& r = row.m_entries[c.m_row_idx]; _row_entry const& r = row.m_entries[c.m_row_idx];
SASSERT(r.m_var == v); SASSERT(r.m_var == v);
SASSERT(r.m_col_idx == i); SASSERT((unsigned)r.m_col_idx == i);
rows.insert(c.m_row_id); rows.insert(c.m_row_id);
} }
int idx = col.m_first_free_idx; int idx = col.m_first_free_idx;

View file

@ -85,7 +85,7 @@ namespace datalog {
removed_cols.size(), removed_cols.c_ptr(), result)); removed_cols.size(), removed_cols.c_ptr(), result));
} }
void compiler::make_select_equal_and_project(reg_idx src, const relation_element & val, unsigned col, void compiler::make_select_equal_and_project(reg_idx src, const relation_element val, unsigned col,
reg_idx & result, bool reuse, instruction_block & acc) { reg_idx & result, bool reuse, instruction_block & acc) {
relation_signature res_sig; relation_signature res_sig;
relation_signature::from_project(m_reg_signatures[src], 1, &col, res_sig); relation_signature::from_project(m_reg_signatures[src], 1, &col, res_sig);
@ -139,7 +139,7 @@ namespace datalog {
return r; return r;
} }
compiler::reg_idx compiler::get_single_column_register(const relation_sort & s) { compiler::reg_idx compiler::get_single_column_register(const relation_sort s) {
relation_signature singl_sig; relation_signature singl_sig;
singl_sig.push_back(s); singl_sig.push_back(s);
return get_fresh_register(singl_sig); return get_fresh_register(singl_sig);
@ -165,7 +165,7 @@ namespace datalog {
} }
} }
void compiler::make_add_constant_column(func_decl* head_pred, reg_idx src, const relation_sort & s, const relation_element & val, void compiler::make_add_constant_column(func_decl* head_pred, reg_idx src, const relation_sort s, const relation_element val,
reg_idx & result, bool & dealloc, instruction_block & acc) { reg_idx & result, bool & dealloc, instruction_block & acc) {
reg_idx singleton_table; reg_idx singleton_table;
if(!m_constant_registers.find(s, val, singleton_table)) { if(!m_constant_registers.find(s, val, singleton_table)) {
@ -185,7 +185,7 @@ namespace datalog {
} }
} }
void compiler::make_add_unbound_column(rule* compiled_rule, unsigned col_idx, func_decl* pred, reg_idx src, const relation_sort & s, reg_idx & result, void compiler::make_add_unbound_column(rule* compiled_rule, unsigned col_idx, func_decl* pred, reg_idx src, const relation_sort s, reg_idx & result,
bool & dealloc, instruction_block & acc) { bool & dealloc, instruction_block & acc) {
TRACE("dl", tout << "Adding unbound column " << mk_pp(pred, m_context.get_manager()) << "\n";); TRACE("dl", tout << "Adding unbound column " << mk_pp(pred, m_context.get_manager()) << "\n";);
@ -862,9 +862,11 @@ namespace datalog {
ast_manager& m = m_context.get_manager(); ast_manager& m = m_context.get_manager();
unsigned pt_len = r->get_positive_tail_size(); unsigned pt_len = r->get_positive_tail_size();
unsigned ut_len = r->get_uninterpreted_tail_size(); unsigned ut_len = r->get_uninterpreted_tail_size();
if (pt_len == ut_len) {
// no negated predicates
if (pt_len == ut_len)
return; return;
}
// populate negative variables: // populate negative variables:
for (unsigned i = pt_len; i < ut_len; ++i) { for (unsigned i = pt_len; i < ut_len; ++i) {
app * neg_tail = r->get_tail(i); app * neg_tail = r->get_tail(i);

View file

@ -135,7 +135,7 @@ namespace datalog {
reg_idx get_fresh_register(const relation_signature & sig); reg_idx get_fresh_register(const relation_signature & sig);
reg_idx get_register(const relation_signature & sig, bool reuse, reg_idx r); reg_idx get_register(const relation_signature & sig, bool reuse, reg_idx r);
reg_idx get_single_column_register(const relation_sort & s); reg_idx get_single_column_register(const relation_sort s);
/** /**
\brief Allocate registers for predicates in \c pred and add them into the \c regs map. \brief Allocate registers for predicates in \c pred and add them into the \c regs map.
@ -150,7 +150,7 @@ namespace datalog {
const unsigned_vector & removed_cols, reg_idx & result, bool reuse_t1, instruction_block & acc); const unsigned_vector & removed_cols, reg_idx & result, bool reuse_t1, instruction_block & acc);
void make_filter_interpreted_and_project(reg_idx src, app_ref & cond, void make_filter_interpreted_and_project(reg_idx src, app_ref & cond,
const unsigned_vector & removed_cols, reg_idx & result, bool reuse, instruction_block & acc); const unsigned_vector & removed_cols, reg_idx & result, bool reuse, instruction_block & acc);
void make_select_equal_and_project(reg_idx src, const relation_element & val, unsigned col, void make_select_equal_and_project(reg_idx src, const relation_element val, unsigned col,
reg_idx & result, bool reuse, instruction_block & acc); reg_idx & result, bool reuse, instruction_block & acc);
/** /**
\brief Create add an union or widen operation and put it into \c acc. \brief Create add an union or widen operation and put it into \c acc.
@ -174,10 +174,10 @@ namespace datalog {
void make_dealloc_non_void(reg_idx r, instruction_block & acc); void make_dealloc_non_void(reg_idx r, instruction_block & acc);
void make_add_constant_column(func_decl* pred, reg_idx src, const relation_sort & s, const relation_element & val, void make_add_constant_column(func_decl* pred, reg_idx src, const relation_sort s, const relation_element val,
reg_idx & result, bool & dealloc, instruction_block & acc); reg_idx & result, bool & dealloc, instruction_block & acc);
void make_add_unbound_column(rule* compiled_rule, unsigned col_idx, func_decl* pred, reg_idx src, const relation_sort & s, reg_idx & result, void make_add_unbound_column(rule* compiled_rule, unsigned col_idx, func_decl* pred, reg_idx src, const relation_sort s, reg_idx & result,
bool & dealloc, instruction_block & acc); bool & dealloc, instruction_block & acc);
void make_full_relation(func_decl* pred, const relation_signature & sig, reg_idx & result, void make_full_relation(func_decl* pred, const relation_signature & sig, reg_idx & result,
instruction_block & acc); instruction_block & acc);

View file

@ -44,7 +44,8 @@ def_module_params(module_name='smt',
('arith.branch_cut_ratio', UINT, 2, 'branch/cut ratio for linear integer arithmetic'), ('arith.branch_cut_ratio', UINT, 2, 'branch/cut ratio for linear integer arithmetic'),
('arith.int_eq_branch', BOOL, False, 'branching using derived integer equations'), ('arith.int_eq_branch', BOOL, False, 'branching using derived integer equations'),
('arith.ignore_int', BOOL, False, 'treat integer variables as real'), ('arith.ignore_int', BOOL, False, 'treat integer variables as real'),
('arith.dump_lemmas', BOOL, False, 'dump arithmetic theory lemmas to files'), ('arith.dump_lemmas', BOOL, False, 'dump arithmetic theory lemmas to files'),
('arith.greatest_error_pivot', BOOL, False, 'Pivoting strategy'),
('pb.conflict_frequency', UINT, 1000, 'conflict frequency for Pseudo-Boolean theory'), ('pb.conflict_frequency', UINT, 1000, 'conflict frequency for Pseudo-Boolean theory'),
('pb.learn_complements', BOOL, True, 'learn complement literals for Pseudo-Boolean theory'), ('pb.learn_complements', BOOL, True, 'learn complement literals for Pseudo-Boolean theory'),
('pb.enable_compilation', BOOL, True, 'enable compilation into sorting circuits for Pseudo-Boolean'), ('pb.enable_compilation', BOOL, True, 'enable compilation into sorting circuits for Pseudo-Boolean'),

View file

@ -308,7 +308,8 @@ namespace smt {
simple_justification(r, num_lits, lits), simple_justification(r, num_lits, lits),
m_num_eqs(num_eqs) { m_num_eqs(num_eqs) {
m_eqs = new (r) enode_pair[num_eqs]; m_eqs = new (r) enode_pair[num_eqs];
memcpy(m_eqs, eqs, sizeof(enode_pair) * num_eqs); if (num_eqs != 0)
memcpy(m_eqs, eqs, sizeof(enode_pair) * num_eqs);
DEBUG_CODE({ DEBUG_CODE({
for (unsigned i = 0; i < num_eqs; i++) { for (unsigned i = 0; i < num_eqs; i++) {
SASSERT(eqs[i].first->get_root() == eqs[i].second->get_root()); SASSERT(eqs[i].first->get_root() == eqs[i].second->get_root());

View file

@ -2789,7 +2789,6 @@ namespace smt {
tout << " --> "; tout << " --> ";
ctx.display_detailed_literal(tout, l); ctx.display_detailed_literal(tout, l);
tout << "\n";); tout << "\n";);
SASSERT(false);
if (ante.lits().size() < small_lemma_size() && ante.eqs().empty()) { if (ante.lits().size() < small_lemma_size() && ante.eqs().empty()) {
literal_vector & lits = m_tmp_literal_vector2; literal_vector & lits = m_tmp_literal_vector2;
lits.reset(); lits.reset();

View file

@ -777,8 +777,8 @@ namespace smt {
// u += ncoeff * lower_bound(v).get_rational(); // u += ncoeff * lower_bound(v).get_rational();
u.addmul(ncoeff, lower_bound(v).get_rational()); u.addmul(ncoeff, lower_bound(v).get_rational());
} }
lower(v)->push_justification(ante, numeral::zero(), coeffs_enabled()); lower(v)->push_justification(ante, it->m_coeff, coeffs_enabled());
upper(v)->push_justification(ante, numeral::zero(), coeffs_enabled()); upper(v)->push_justification(ante, it->m_coeff, coeffs_enabled());
} }
else if (gcds.is_zero()) { else if (gcds.is_zero()) {
gcds = abs_ncoeff; gcds = abs_ncoeff;

View file

@ -88,6 +88,22 @@ class fpa2bv_tactic : public tactic {
new_pr = m.mk_modus_ponens(pr, new_pr); new_pr = m.mk_modus_ponens(pr, new_pr);
} }
g->update(idx, new_curr, new_pr, g->dep(idx)); g->update(idx, new_curr, new_pr, g->dep(idx));
if (is_app(new_curr)) {
const app * a = to_app(new_curr.get());
if (a->get_family_id() == m_conv.fu().get_family_id() &&
a->get_decl_kind() == OP_FPA_IS_NAN) {
// Inject auxiliary lemmas that fix e to the one and only NaN value,
// that is (= e (fp #b0 #b1...1 #b0...01)), so that the value propagation
// has a value to propagate.
expr * sgn, *sig, *exp;
expr_ref top_exp(m);
m_conv.split_fp(new_curr, sgn, exp, sig);
m.mk_eq(sgn, m_conv.bu().mk_numeral(0, 1));
m.mk_eq(exp, m_conv.bu().mk_numeral(-1, m_conv.bu().get_bv_size(exp)));
m.mk_eq(sig, m_conv.bu().mk_numeral(1, m_conv.bu().get_bv_size(sig)));
}
}
} }
if (g->models_enabled()) if (g->models_enabled())

View file

@ -35,9 +35,9 @@ Notes:
tactic * mk_default_tactic(ast_manager & m, params_ref const & p) { tactic * mk_default_tactic(ast_manager & m, params_ref const & p) {
tactic * st = using_params(and_then(mk_simplify_tactic(m), tactic * st = using_params(and_then(mk_simplify_tactic(m),
cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m), cond(mk_is_qfbv_probe(), mk_qfbv_tactic(m),
cond(mk_is_qfaufbv_probe(), mk_qfaufbv_tactic(m), cond(mk_is_qfaufbv_probe(), mk_qfaufbv_tactic(m),
cond(mk_is_qfauflia_probe(), mk_qfauflia_tactic(m),
cond(mk_is_qflia_probe(), mk_qflia_tactic(m), cond(mk_is_qflia_probe(), mk_qflia_tactic(m),
cond(mk_is_qfauflia_probe(), mk_qfauflia_tactic(m),
cond(mk_is_qflra_probe(), mk_qflra_tactic(m), cond(mk_is_qflra_probe(), mk_qflra_tactic(m),
cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m), cond(mk_is_qfnra_probe(), mk_qfnra_tactic(m),
cond(mk_is_qfnia_probe(), mk_qfnia_tactic(m), cond(mk_is_qfnia_probe(), mk_qfnia_tactic(m),

View file

@ -24,7 +24,8 @@ Notes:
#include"polynomial_factorization.h" #include"polynomial_factorization.h"
#endif #endif
using namespace std; using std::cout;
using std::endl;
// some prime numbers // some prime numbers
unsigned primes[] = { unsigned primes[] = {

View file

@ -19,11 +19,18 @@ Revision History:
#include"debug.h" #include"debug.h"
#include"hash.h" #include"hash.h"
#include <string.h>
static unsigned read_unsigned(const char *s) {
unsigned n;
memcpy(&n, s, sizeof(unsigned));
return n;
}
// I'm using Bob Jenkin's hash function. // I'm using Bob Jenkin's hash function.
// http://burtleburtle.net/bob/hash/doobs.html // http://burtleburtle.net/bob/hash/doobs.html
unsigned string_hash(const char * str, unsigned length, unsigned init_value) { unsigned string_hash(const char * str, unsigned length, unsigned init_value) {
register unsigned a, b, c, len; unsigned a, b, c, len;
/* Set up the internal state */ /* Set up the internal state */
len = length; len = length;
@ -31,10 +38,11 @@ unsigned string_hash(const char * str, unsigned length, unsigned init_value) {
c = init_value; /* the previous hash value */ c = init_value; /* the previous hash value */
/*---------------------------------------- handle most of the key */ /*---------------------------------------- handle most of the key */
SASSERT(sizeof(unsigned) == 4);
while (len >= 12) { while (len >= 12) {
a += reinterpret_cast<const unsigned *>(str)[0]; a += read_unsigned(str);
b += reinterpret_cast<const unsigned *>(str)[1]; b += read_unsigned(str+4);
c += reinterpret_cast<const unsigned *>(str)[2]; c += read_unsigned(str+8);
mix(a,b,c); mix(a,b,c);
str += 12; len -= 12; str += 12; len -= 12;
} }

View file

@ -16,7 +16,9 @@ Author:
Revision History: Revision History:
--*/ --*/
#include<math.h>
#include<float.h> #include<float.h>
#include<sstream>
#ifdef _WINDOWS #ifdef _WINDOWS
#pragma float_control( except, on ) // exception semantics; this does _not_ mean that exceptions are enabled (we want them off!) #pragma float_control( except, on ) // exception semantics; this does _not_ mean that exceptions are enabled (we want them off!)
@ -24,19 +26,13 @@ Revision History:
#pragma fp_contract(off) // contractions off (`contraction' means x*y+z is turned into a fused-mul-add). #pragma fp_contract(off) // contractions off (`contraction' means x*y+z is turned into a fused-mul-add).
#pragma fenv_access(on) // fpu environment sensitivity (needed to be allowed to make FPU mode changes). #pragma fenv_access(on) // fpu environment sensitivity (needed to be allowed to make FPU mode changes).
#else #else
#ifdef _WINDOWS #include<fenv.h>
#pragma STDC FENV_ACCESS ON
#endif
#include <math.h>
#include <fenv.h>
#endif #endif
#ifndef _M_IA64 #ifndef _M_IA64
#define USE_INTRINSICS #define USE_INTRINSICS
#endif #endif
#include<sstream>
#include"hwf.h" #include"hwf.h"
// Note: // Note:
@ -57,7 +53,7 @@ Revision History:
hwf_manager::hwf_manager() : hwf_manager::hwf_manager() :
m_mpz_manager(m_mpq_manager) m_mpz_manager(m_mpq_manager)
{ {
#ifdef _WINDOWS #ifdef _WINDOWS
#if defined(_AMD64_) || defined(_M_IA64) #if defined(_AMD64_) || defined(_M_IA64)
// Precision control is not supported on x64. // Precision control is not supported on x64.
@ -310,14 +306,28 @@ void hwf_manager::fma(mpf_rounding_mode rm, hwf const & x, hwf const & y, hwf co
// CMW: fused_mul_add is not available on most CPUs. As of 2012, only Itanium, // CMW: fused_mul_add is not available on most CPUs. As of 2012, only Itanium,
// Intel Sandybridge and AMD Bulldozers support that (via AVX). // Intel Sandybridge and AMD Bulldozers support that (via AVX).
#ifdef _M_IA64
// IA64 (Itanium) will do it, if contractions are on.
set_rounding_mode(rm); set_rounding_mode(rm);
#ifdef _M_IA64
// IA64 (Itanium) will do it, if contractions are on.
o.value = x.value * y.value + z.value; o.value = x.value * y.value + z.value;
#else #else
set_rounding_mode(rm); #if defined(_WINDOWS)
#if _MSC_VER >= 1800
o.value = ::fma(x.value, y.value, z.value);
#else // Windows, older than VS 2013
#ifdef USE_INTRINSICS
_mm_store_sd(&o.value, _mm_fmadd_sd(_mm_set_sd(x.value), _mm_set_sd(y.value), _mm_set_sd(z.value)));
#else
// If all else fails, we are imprecise.
o.value = (x.value * y.value) + z;
#endif
#endif
#else
// Linux, OSX
o.value = ::fma(x.value, y.value, z.value); o.value = ::fma(x.value, y.value, z.value);
#endif #endif
#endif
} }
#ifdef _M_IA64 #ifdef _M_IA64

View file

@ -19,9 +19,9 @@ Revision History:
#include<sstream> #include<sstream>
#include"inf_int_rational.h" #include"inf_int_rational.h"
inf_int_rational inf_int_rational::m_zero(0); inf_int_rational inf_int_rational::m_zero;
inf_int_rational inf_int_rational::m_one(1); inf_int_rational inf_int_rational::m_one;
inf_int_rational inf_int_rational::m_minus_one(-1); inf_int_rational inf_int_rational::m_minus_one;
std::string inf_int_rational::to_string() const { std::string inf_int_rational::to_string() const {
if (m_second == 0) { if (m_second == 0) {
@ -39,3 +39,22 @@ std::string inf_int_rational::to_string() const {
return s.str(); return s.str();
} }
void initialize_inf_int_rational() {
inf_int_rational::init();
}
void inf_int_rational::init() {
m_zero.m_first = rational::zero();
m_one.m_first = rational::one();
m_minus_one.m_first = rational::minus_one();
}
void finalize_inf_int_rational() {
inf_int_rational::finalize();
}
void inf_int_rational::finalize() {
m_zero.~inf_int_rational();
m_one.~inf_int_rational();
m_minus_one.~inf_int_rational();
}

View file

@ -33,6 +33,8 @@ class inf_int_rational {
rational m_first; rational m_first;
int m_second; int m_second;
public: public:
static void init(); // called from rational::initialize() only
static void finalize(); // called from rational::finalize() only
unsigned hash() const { unsigned hash() const {
return m_first.hash() ^ (static_cast<unsigned>(m_second) + 1); return m_first.hash() ^ (static_cast<unsigned>(m_second) + 1);
@ -272,7 +274,7 @@ class inf_int_rational {
if (r.m_second >= 0) { if (r.m_second >= 0) {
return r.m_first; return r.m_first;
} }
return r.m_first - rational(1); return r.m_first - rational::one();
} }
return floor(r.m_first); return floor(r.m_first);
@ -283,7 +285,7 @@ class inf_int_rational {
if (r.m_second <= 0) { if (r.m_second <= 0) {
return r.m_first; return r.m_first;
} }
return r.m_first + rational(1); return r.m_first + rational::one();
} }
return ceil(r.m_first); return ceil(r.m_first);

View file

@ -18,9 +18,9 @@ Revision History:
--*/ --*/
#include"inf_rational.h" #include"inf_rational.h"
inf_rational inf_rational::m_zero(0); inf_rational inf_rational::m_zero;
inf_rational inf_rational::m_one(1); inf_rational inf_rational::m_one;
inf_rational inf_rational::m_minus_one(-1); inf_rational inf_rational::m_minus_one;
inf_rational inf_mult(inf_rational const& r1, inf_rational const& r2) inf_rational inf_mult(inf_rational const& r1, inf_rational const& r2)
{ {
@ -128,7 +128,7 @@ inf_rational inf_power(inf_rational const& r, unsigned n)
// 0 will work. // 0 will work.
} }
else if (r.m_first.is_zero()) { else if (r.m_first.is_zero()) {
result.m_first = rational(-1); result.m_first = rational::minus_one();
} }
else if (r.m_first.is_pos()) { else if (r.m_first.is_pos()) {
result.m_first = rational(r.m_first - r.m_first/rational(2)).expt(n); result.m_first = rational(r.m_first - r.m_first/rational(2)).expt(n);
@ -152,7 +152,7 @@ inf_rational sup_power(inf_rational const& r, unsigned n)
result.m_first = r.m_first.expt(n); result.m_first = r.m_first.expt(n);
} }
else if (r.m_first.is_zero() || (n == 0)) { else if (r.m_first.is_zero() || (n == 0)) {
result.m_first = rational(1); result.m_first = rational::one();
} }
else if (r.m_first.is_pos() || is_even) { else if (r.m_first.is_pos() || is_even) {
result.m_first = rational(r.m_first + r.m_first/rational(2)).expt(n); result.m_first = rational(r.m_first + r.m_first/rational(2)).expt(n);
@ -177,3 +177,23 @@ inf_rational sup_root(inf_rational const& r, unsigned n)
// use r. // use r.
return r; return r;
} }
void initialize_inf_rational() {
inf_rational::init();
}
void inf_rational::init() {
m_zero.m_first = rational::zero();
m_one.m_first = rational::one();
m_minus_one.m_first = rational::minus_one();
}
void finalize_inf_rational() {
inf_rational::finalize();
}
void inf_rational::finalize() {
m_zero.~inf_rational();
m_one.~inf_rational();
m_minus_one.~inf_rational();
}

View file

@ -33,6 +33,8 @@ class inf_rational {
rational m_first; rational m_first;
rational m_second; rational m_second;
public: public:
static void init(); // called from rational::initialize() only
static void finalize(); // called from rational::finalize() only
unsigned hash() const { unsigned hash() const {
return m_first.hash() ^ (m_second.hash()+1); return m_first.hash() ^ (m_second.hash()+1);
@ -40,7 +42,7 @@ class inf_rational {
struct hash_proc { unsigned operator()(inf_rational const& r) const { return r.hash(); } }; struct hash_proc { unsigned operator()(inf_rational const& r) const { return r.hash(); } };
struct eq_proc { bool operator()(inf_rational const& r1, inf_rational const& r2) const { return r1 == r2; } }; struct eq_proc { bool operator()(inf_rational const& r1, inf_rational const& r2) const { return r1 == r2; } };
void swap(inf_rational & n) { void swap(inf_rational & n) {
m_first.swap(n.m_first); m_first.swap(n.m_first);
@ -82,7 +84,7 @@ class inf_rational {
explicit inf_rational(rational const& r, bool pos_inf): explicit inf_rational(rational const& r, bool pos_inf):
m_first(r), m_first(r),
m_second(pos_inf?rational(1):rational(-1)) m_second(pos_inf ? rational::one() : rational::minus_one())
{} {}
inf_rational(rational const& r): inf_rational(rational const& r):
@ -313,7 +315,7 @@ class inf_rational {
if (r.m_second.is_nonneg()) { if (r.m_second.is_nonneg()) {
return r.m_first; return r.m_first;
} }
return r.m_first - rational(1); return r.m_first - rational::one();
} }
return floor(r.m_first); return floor(r.m_first);
@ -324,7 +326,7 @@ class inf_rational {
if (r.m_second.is_nonpos()) { if (r.m_second.is_nonpos()) {
return r.m_first; return r.m_first;
} }
return r.m_first + rational(1); return r.m_first + rational::one();
} }
return ceil(r.m_first); return ceil(r.m_first);

View file

@ -348,7 +348,7 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode
bool sticky = false; bool sticky = false;
while (ds < 0) while (ds < 0)
{ {
if (!m_mpz_manager.is_even(o.significand)) sticky = true; sticky |= m_mpz_manager.is_odd(o.significand);
m_mpz_manager.machine_div2k(o.significand, 1); m_mpz_manager.machine_div2k(o.significand, 1);
ds++; ds++;
} }

View file

@ -29,9 +29,9 @@ rational rational::m_one;
rational rational::m_minus_one; rational rational::m_minus_one;
vector<rational> rational::m_powers_of_two; vector<rational> rational::m_powers_of_two;
void mk_power_up_to(vector<rational> & pws, unsigned n) { static void mk_power_up_to(vector<rational> & pws, unsigned n) {
if (pws.empty()) { if (pws.empty()) {
pws.push_back(rational(1)); pws.push_back(rational::one());
} }
unsigned sz = pws.size(); unsigned sz = pws.size();
rational curr = pws[sz - 1]; rational curr = pws[sz - 1];
@ -53,16 +53,28 @@ rational rational::power_of_two(unsigned k) {
return result; return result;
} }
// in inf_rational.cpp
void initialize_inf_rational();
void finalize_inf_rational();
// in inf_int_rational.cpp
void initialize_inf_int_rational();
void finalize_inf_int_rational();
void rational::initialize() { void rational::initialize() {
if (!g_mpq_manager) { if (!g_mpq_manager) {
g_mpq_manager = alloc(synch_mpq_manager); g_mpq_manager = alloc(synch_mpq_manager);
m().set(m_zero.m_val, 0); m().set(m_zero.m_val, 0);
m().set(m_one.m_val, 1); m().set(m_one.m_val, 1);
m().set(m_minus_one.m_val, -1); m().set(m_minus_one.m_val, -1);
initialize_inf_rational();
initialize_inf_int_rational();
} }
} }
void rational::finalize() { void rational::finalize() {
finalize_inf_rational();
finalize_inf_int_rational();
m_powers_of_two.finalize(); m_powers_of_two.finalize();
m_zero.~rational(); m_zero.~rational();
m_one.~rational(); m_one.~rational();