Can I check whether a variable has deterministic value by C++ API - c++

I noticed that Z3 can do allsmt from some paper. In my project, I have to search for deterministic variables in a SMT formula. By deterministic I mean the variable can only take one int value to make the formula satisfiable. Is there a c++/c API function which can do this task?
The best I can do so far is to call the solver.check() function many times for the negation of each variable I am interested in. Is there a faster way to do this by using the API?
Basically, I want to do allsmt and predicate abstraction/projection.

There is no specialized API for checking if all models of a given variable have to agree on the same value. You can implement more or less efficient algorithms on top of Z3 to solve this question.
Here is a possible algorithm:
Get a model M from Z3.
For the variables you are interested in assert: Not (And([(M.eval(x) == x) for x in Vars]))
Recheck satisfiability. If the new state is unsatisfiable, then the remaining variales in Vars must have the same value. Otherwise, remove variables from Vars that evaluate to a new value different from the old M.eval(x), and repeat (2) until Vars is either empty or the context is unsatisfiable.

Related

Piecewise function with variable values at domain breakpoints

In our model we need a set of equations
model.y[k] = model.F(model.x[k]) (where k is in a proper Set)
with piecewise function F(x) defined on a fixed set of domain variable (breakpoints), but with unknown, variable (!), values at these breakpoints.
I implemented the case via SOSConstraint(..., sos=2) and it works (I tested by SCIP solver).
Now we want to try other implementations of pw-functions (LOG, BIGM_BIN, DCC, DLOG, etc.) mentioned in Pyomo pyomo.core.base.piecewise.Piecewise code. But it seems that this class requires fixed numerical values for F(x) at all breakpoints. If a function passed by f_rule argument to Piecewise constructor returns Pyomo expression with variable, then I get the following error:
ERROR: evaluating object as numeric value: ...
Can somebody give an advice or an a reference to some example of a "variable" piecewise-function ?
E.g., regarding "LOG" representation (from Vielma etc.) I see the code of _LOGPiecewise function in pyomo/core/base/piecewise.py module. And I do not see any reasons to forbidden to use variables as "y"-values of pw-expression being constructed ...
Updated
I've succeeded to modify pyomo.core.base.piecewise module to use variables as values of pw-function. Frankly speaking, these "modifications" were just commenting of some fragments in piecewise.py...
But, for my problem, I did not get any speed up in comparison with SOSConstraint (for SCIP solver !).
Can anybody give the benefit of experience: what pw-models were faster SOSConstraint or LOG, BIGM_BIN, DCC, DLOG for other problems ?

CUDD C++ Interface for converting Booleans to BDDs and resulting set of minterms (to cutsets)

I'm working with (https://github.com/ivmai/cudd) with the goal of the following repetitive process:
(1) Input: (Coherent, non-decreasing) Boolean function expression
top = a_1a_2a_3...+ x_1x_2x_3... + z_1z_2z_3...). The Booleans I'm working with have
thousands of vars (ai...zj) and hundreds of terms.
(2) Processing: Convert Boolean to a BDD to simplify the calculation of the minterms, or mutually
exclusive cut-sets (as we call them in the Reliability world).
(3) Output: Take the set of m.e. minimal cutsets (minterms). Calculate the top event probability by
adding up all the minterms found in (2).
I've found a way to do this with a labor-intensive manual C interface to build the Boolean. I've also found how to do it with the excellent tulip-dd Py interface, but unable to make it scale as with cudd.
Now I'm hoping with the C++ interface to cudd I can get the best of both worlds (Am I asking for too much?) Namely, the convenience of say tulip-dd with the scalability of cudd. So here's some sample code. Where I'm failing is in step 3, printing out the minterms, which I used to be able to do in C. How do I do it with the C++ interface?! Please see comments in the code for my specific thoughts and attempts.
int main()
{
/*DdManager* gbm; /* Global BDD manager. I suppose we do not use this if we use the Cudd type below.*/
/* (1-2) Declare the vars and build the Boolean. Convert Boolean to BDD */
Cudd mgr(0, 0);
BDD a = mgr.bddVar();
BDD b = mgr.bddVar();
BDD c = mgr.bddVar();
BDD d = mgr.bddVar();
BDD e = mgr.bddVar();
BDD top = a*(b + c + d*e);
/* How to print out the equivalent to below, which prints out all minterms and their relevant vars in C.
But the mgr below has to be a *DManager ? If so, how to convert? */
Cudd_PrintDebug(mgr, BDD, 2, 4);
return 0
}
Thanks,
Gui
The CUDD C++ classes are very little more than a wrapper around the "DdManager*" and "DdNode*" data types. They make sure that you don't accidentally forget to Cudd_Ref(..) or Cudd_RecursiveDeref(...) *DD nodes that you are using.
As such, these classes have functions that you can use to access the underlying data types. So for instance, if you want to call the "Cudd_PrintDebug" function on the "top" BDD, then you can do that with:
Cudd_PrintDebug(mgr.getManager(), top.getNode(), 2, 4);
The modification to your code was minimal.
Note that when using a plain CUDD DdNode* that you obtain with the "getNode" function, you have to make sure manually that you don't introduce node count leaks. If you use the DdNodes in a "read only fashion", only store DdNode* that correspond to BDD objects that you also store, and make sure that the BDD objects always live longer than the DdNode* pointers, this does not happen, though.
I'm only mentioning this since at some point you may want to iterate through the cubes of a BDD. These are essentially not-guaranteed-to-be-minimal minterms. There are special iterators in CUDD for this. However, if you really want the minterms, this may not be right approach. There is other software using CUDD that comes with its own functions for enumerating the minterms.
As a final note (outside of the scope of StackOverflow), you wrote that "The Booleans I'm working with have thousands of vars (ai...zj) and hundreds of terms." - There is no guarantee that using BDDs with so many variables is the way to go here. But please try it out. Having thousands of variables is often problematic for BDD-based approaches. Your application may or may not be an exception to this observation. An alternative approach may be to encode the search problem for all minterms of your original expression as an incremental satisfiability (SAT) solving problem.

Is there a way to generate a new variable only if it meets certain criteria?

I am trying to replicate the following Stata code in R:
gen UAPDL_1=sqrt((((Sanchez_1-Iglesias_1)^2)+((Casado_1-Iglesias_1)^2)+((Rivera_1-Iglesias_1)^2))/3) if maxIglesias_1==1
replace UAPDL_1=sqrt((((Sanchez_1-Rivera_1)^2)+((Casado_1-Rivera_1)^2)+((Iglesias_1-Rivera_1)^2))/3) if maxRivera_1==1
In other words, I am trying to make different calculations and generate a new variable with different values depending on certain conditions (in this case, they have value 1 in an another variable. I managed to create the variables to be met for making the calculation (maxIglesias==1 and maxRivera==1), but I am stuck in the generation of the UAPDL variable. I tried with case_when and ifelse, but in these cases these commands only let you define a certain value. Is there a way with mutate or dplyr (or any other package) to achieve this goal?
Welcome to SO!
Let me try to 'parse' your question for the sake of clarity.
You want to generate a variable UAPDL depending on the value of two distinct variables (maxIglesias_1 and maxRivera_1, which let's say correspond to values f(I) and f(R), respectively). Here I note that, according to the snippet of the code you posted, there is no guarantee that the two variables are mutually exclusive - i.e., you may have records with maxIglesias_1 == 1 AND maxRivera_1 == 1. In those cases, the order in which you run the commands matters, as they all end up valued f(R), or f(I) if you twist them.
However, in order to replicate the Stata commands that you posted (issue with the ordering included!) you should run
UAPDL_1 <- numeric(length(maxIglesias_1)) # generate the vector
UAPDL_1[maxIglesias_1 == 1] <- f(I)
UAPDL_1[maxRivera_1 == 1] <- f(R)
where I assume that maxIglesias_1 and maxIglesias_1 are two R objects of the same length as the original Stata matrix.
Good luck!

Using Brent algorithm to find the root of a function f with an initial guess, but without intervals [a,b] s.t. f(a)f(b)<0

I would like to know how to use Brent algorithm if no opposite signs can be provided.
For example, in the C++ library of Brent algorithm, the root-finding procedure that implements Brent’s method has to be used, following the header file, in the form of
double zero ( double a, double b, double t, func_base& f );
where a, b satisfies the condition of opposite signs: f(a).f(b) < 0
In my problem setting, I need to find the root(s) of a black-box function f. An initial guess is provided but no endpoints a,b, such that f(a) f(b)<0 are provided It seems that in Matlab there is a function fmin that only needs an initial guess. I would like to know how to do this using C++, in particular, using the implementation of Brent such as the one linked above?
Thanks for your ideas.
Without doing exhaustive search (and in the case of real valued function, you cannot, since the value of x is uncountable), there is no way to really guarantee finding the root if such exist.
One heuristic approach to address the problem is using gradient descent, in order to minimze (/maximize) the value of the function, until you find a local minimum (/maximum) or until you find a root.
The problem with this approach is you can get stuck in a local minimum (/maximum) before finding the root, and "think" there is no root, even if one does exist.
Under the assumptions that
f is a black-box, i.e. it can be evaluated but no information on its shape is known whatsoever.
You have to use a method that requires a priori knowledge of an interval [a,b] which brackets a root of f (assuming f is continuous).
I think your only option is to make a preliminary search for two valid points a and b.
This can be done in a number of ways. The most simple-minded could be to run a linear search (with some prescribed step) starting from your initial guess, which can be repeated with a finer step if it turns out unsuccessful. If f is not too "weird" a simple method should do.
Clearly, some basic clue on the properties of f is always necessary, for example that it actually has a root and that it is continuos, differentiable, etc.. All root finding methods (gradient descent, Newton-Raphson, bisection, etc.) assume some basic properties of the function.

calculating user defined formulas (with c++)

We would like to have user defined formulas in our c++ program.
e.g. The value v = x + ( y - (z - 2)) / 2. Later in the program the user would define x,y and z -> the program should return the result of the calculation. Somewhen later the formula may get changed, so the next time the program should parse the formula and add the new values. Any ideas / hints how to do something like this ? So far I just came to the solution to write a parser to calculate these formulas - maybe any ideas about that ?
If it will be used frequently and if it will be extended in the future, I would almost recommend adding either Python or Lua into your code. Lua is a very lightweight scripting language which you can hook into and provide new functions, operators etc. If you want to do more robust and complicated things, use Python instead.
You can represent your formula as a tree of operations and sub-expressions. You may want to define types or constants for Operation types and Variables.
You can then easily enough write a method that recurses through the tree, applying the appropriate operations to whatever values you pass in.
Building your own parser for this should be a straight-forward operation:
) convert the equation from infix to postfix notation (a typical compsci assignment) (I'd use a stack)
) wait to get the values you want
) pop the stack of infix items, dropping the value for the variable in where needed
) display results
Using Spirit (for example) to parse (and the 'semantic actions' it provides to construct an expression tree that you can then manipulate, e.g., evaluate) seems like quite a simple solution. You can find a grammar for arithmetic expressions there for example, if needed... (it's quite simple to come up with your own).
Note: Spirit is very simple to learn, and quite adapted for such tasks.
There's generally two ways of doing it, with three possible implementations:
as you've touched on yourself, a library to evaluate formulas
compiling the formula into code
The second option here is usually done either by compiling something that can be loaded in as a kind of plugin, or it can be compiled into a separate program that is then invoked and produces the necessary output.
For C++ I would guess that a library for evaluation would probably exist somewhere so that's where I would start.
If you want to write your own, search for "formal automata" and/or "finite state machine grammar"
In general what you will do is parse the string, pushing characters on a stack as you go. Then start popping the characters off and perform tasks based on what is popped. It's easier to code if you force equations to reverse-polish notation.
To make your life easier, I think getting this kind of input is best done through a GUI where users are restricted in what they can type in.
If you plan on doing it from the command line (that is the impression I get from your post), then you should probably define a strict set of allowable inputs (e.g. only single letter variables, no whitespace, and only certain mathematical symbols: ()+-*/ etc.).
Then, you will need to:
Read in the input char array
Parse it in order to build up a list of variables and actions
Carry out those actions - in BOMDAS order
With ANTLR you can create a parser/compiler that will interpret the user input, then execute the calculations using the Visitor pattern. A good example is here, but it is in C#. You should be able to adapt it quickly to your needs and remain using C++ as your development platform.