Clingo: How to do "If p causes UNSAT then q." - answer-set-programming

In the code below
% Facts
a.
% Rules
-a :- a, not not p.
Adding the fact p. to the above would cause it to be UNSAT. Is there a way in clingo to add a rule to show this? Something like
q :- Assuming p causes UNSAT.
Solutions like adding the rule
{p; q} = 1.
Wouldn't work. It would give q. in the answer set if p. causes UNSAT, as I'd want. But, it would give p. and q. as answer sets when p. doesn't cause UNSAT. In the case of p. not causing UNSAT I wouldn't want q. in the answer set.
I'd like to be able to check whether certain facts causes a certain complex condition to not hold. For example, suppose one part of a problem requires you to check that a graph does NOT contain a Hamiltonian cycle. A program that finds Hamiltonian cycles would return UNSAT if the graph satisfies the condition, but I wouldn't want the program to end, since there would be other calculations to do.

You can probably treat it as an optimisation problem. So something that would normally be a constraint is turned into a special predicate which you then seek to minimise. Basically you have something of the form:
err(err1) :- some-bad-condition.
err(err2) :- some-other-bad-condition.
#minimize{ 1,XXX: err(XXX) }.
Here the XXX is a unique identifier for each error condition. The optimisation statement finds a model that minimises the number of errs.
The only caveat is that this increases the complexity of the problem; you're now solving an optimisation problem instead of a decision problem. It is a useful trick when debugging asp programs, but for large/difficult problems it may be too slow.

Related

Prove a Boolean formula under some Implies conditions in z3py

I'm new in using Z3py, and my assignment is to generate counter examples for both solutions (sat and unsat).
Is there any function to generate counterexample for unsat solution?
unsat means there is no model that satisfies the assertions given. You can only extract a model when the problem is sat. So, to answer your question as you posed it, you cannot create models from an unsat solution: It just does not exist.
A typical approach is to assert the negation of the formula you are trying to prove; and if that formula is satisfiable then your original formula is falsifiable; i.e., there is a counter-example for it. Perhaps that's what you are trying to do? That is: If the negation of the formula has a satisfying model, then that model is a counter-example for the original formula. This is how most provers built on top of SMT solvers work, by sending the negation of what they are trying to prove and getting back unsat. If the prover returns a model, then it is a counter-example.

Replace values in an array in matlab without changing the original array

My question is that given an array A, how can you give another array identical to A except changing all negatives to 0 (without changing values in A)?
My way to do this is:
B = A;
B(B<0)=0
Is there any one-line command to do this and also not requiring to create another copy of A?
While this particular problem does happen to have a one-liner solution, e.g. as pointed out by Luis and Ian's suggestions, in general if you want a copy of a matrix with some operation performed on it, then the way to do it is exactly how you did it. Matlab doesn't allow chained operations or compound expressions, so you generally have no choice but to assign to a temporary variable in this manner.
However, if it makes you feel better, B=A is efficient as it will not result in any new allocated memory, unless / until B or A change later on. In other words, before the B(B<0)=0 step, B is simply a reference to A and takes no extra memory. This is just how matlab works under the hood to ensure no memory is wasted on simple aliases.
PS. There is nothing efficient about one-liners per se; in fact, you should avoid them if they lead to obscure code. It's better to have things defined over multiple lines if it makes the logic and intent of the algorithm clearer.
e.g, this is also a valid one-liner that solves your problem:
B = subsasgn(A, substruct('()',{A<0}), 0)
This is in fact the literal answer to your question (i.e. this is pretty much code that matlab will call under the hood for your commands). But is this clearer, more elegant code just because it's a one-liner? No, right?
Try
B = A.*(A>=0)
Explanation:
A>=0 - create matrix where each element is 1 if >= 0, 0 otherwise
A.*(A>=0) - multiply element-wise
B = A.*(A>=0) - Assign the above to B.

Speeding up integration methods MATLAB

I am using MATLAB to execute a triple integral using integral3 and it is running very slow. I was wondering if there ways to speed it. I am guessing its due to the fact that I set the abstol wrong. Not sure how to handle it. PS the code below works with no syntax error. There are a couple of things I dont know how to pick, abstol, method etc..
clear all
syms gamma1
syms gamma2
syms z
syms v
Nt=16; sigmanoise=10^(-7.9); c3=0.129; c1=(1-c3)/2;a2=0;b2=0;
a1=0.0030; b1= 0.0030; A1= 1.5625e-04,A2=0; B1= 7.8125e-05;B2=0;
theta= 3.1623;lambda1= 4.9736e-05;lambda2=0;p1=1;p2=0; alpha1=2; alpha2=4;delta1=2/alpha1; delta2=2/alpha2;beta1=0.025; beta2=0.025;
a= gamma1^-1+gamma2^-1+2*gamma1^(-0.5)*gamma2^(-0.5);
laplacesgi=(exp(+2*pi*j.*z*a)-1)./(2*pi*j*z);
laplacesgi=matlabFunction(laplacesgi);
laplacenoi=exp(-2*pi*j.*z*theta*sigmanoise/Nt);
laplacenoi=matlabFunction(laplacenoi);
interfere= #(gamma1,gamma2,v,z)( (1 -2*c1-c3./(1+2*pi*j*z*theta*v.^(-1))).*(A1.*(v).^(delta1-1).*exp(-a1.*(v).^ (delta1./2))+B1.*(v).^(delta2-1) .*(1-exp(-b1.*(v).^ (delta2./2)))));
gscalar =#(gamma1,gamma2,z)integral(#(v)(interfere(gamma1,gamma2,v,z)),gamma2,inf);
g = #(gamma1,gamma2,z)arrayfun(gscalar,gamma1,gamma2,z);
lp= A1*(gamma1)^(delta1-1)*exp(-a1*(gamma1)^ (delta1/2))+B1*(gamma1)^(delta2-1)*(1-exp(-b1*(gamma1)^ (delta2/2)))+A2*gamma1^(delta1-1)*exp(-a2*gamma1^(delta1/2))+ B2*gamma1^(delta2-1)*(1-exp(-b2*gamma1^ (delta2/2)));%;
dk1=((2*pi*lambda1))/(beta1^2)*(1-exp(-a1*(gamma2)^(delta1/2))*(1+(gamma2)^(delta1/2)*a1))+ pi*lambda1*gamma2^(delta2)*p1^delta2-((2*pi*lambda1)/(beta1^2))*(1-exp(-b1*(gamma2)^(delta2/2))*(1+(gamma2)^(delta2/2)*b1));
dk2=((2*pi*lambda2))/(beta2^2)*(1-exp(-a2*(gamma2)^(delta1/2))*(1+(gamma2)^(delta1/2)*a2))+ pi*lambda2*gamma2^(delta2)*p2^delta2-((2*pi*lambda2)/(beta2^2))*(1-exp(-b2*(gamma2)^(delta2/2))*(1+(gamma2)^(delta2/2)*b2));
dk=dk1+dk2;
lcp= A1*(gamma2)^(delta1-1)*exp(-a1*(gamma2)^ (delta1/2))+B1*(gamma2)^(delta2-1)*(1-exp(-b1*(gamma2)^ (delta2/2)))+A2*gamma2^(delta1-1)*exp(-a2*gamma2^ (delta1/2))+ B2*gamma2^(delta2-1)*(1-exp(-b2*gamma2^(delta2/2)));%;
pdflast=lp*lcp*exp(-dk);
pdflast=matlabFunction(pdflast);
pdflast= #(gamma1,gamma2)arrayfun(pdflast,gamma1,gamma2);
gamma2min=#(gamma1)gamma1;
warning('off','MATLAB:integral:MinStepSize');
T = integral3(#(gamma1,gamma2,z)(laplacenoi(z).*laplacesgi(gamma1,gamma2,z).*pdflast(gamma1,gamma2).*exp(-g(gamma1,gamma2,z))),0,inf,#(gamma2)gamma2,inf,0.05,1000,'abstol',1e-3)
I appreciate any ideas or suggestions.
This is getting way too long for a comment, and while it doesn't really give an answer either, I think it may be helpful anyway, so I will slightly abuse the answer form for it.
Code Readability
I don't think your code as it stands fulfills the basic fundamental purpose of code: Communicating with a human being, probably yourself down the road.
I don't know if the variable names are unambiguous enough that in six months, they will still tell you exactly what is what. If they are, great. If not, you may want to improve upon them. (And yes, naming stuff is one of the hardest parts of programming, but that doesn't make it less important.)
The same holds true for comments: If you don't need comments on your formulas, more power to you. I have no idea what you are computing, so the fact that I don't understand your formulas doesn't mean much. But again, think of yourself in a few months, looking for a problem: Would you have wished for a comment such that you know if that factor is really correct or off by one?
Here's something I do know: Your formulas are simply too wide to be comprehended at once. Simple reformatting helps to see the structure better. Here's how I reformatted your code to start making heads or tails from it:
clear all
syms gamma1
syms gamma2
syms z
syms v
Nt=16;
sigmanoise=10^(-7.9);
c3=0.129;
c1=(1-c3)/2;
a2=0;
b2=0;
a1=0.0030;
b1=0.0030;
A1=1.5625e-04;
A2=0;
B1=7.8125e-05;
B2=0;
theta=3.1623;
lambda1=4.9736e-05;
lambda2=0;
p1=1;
p2=0;
alpha1=2;
alpha2=4;
delta1=2/alpha1;
delta2=2/alpha2;
beta1=0.025;
beta2=0.025;
a=gamma1^(-1)+gamma2^(-1)+2*gamma1^(-0.5)*gamma2^(-0.5);
laplacesgi=matlabFunction((exp(2*pi*1j*z*a)-1)./(2*pi*1j*z));
laplacenoi=matlabFunction(exp(-2*pi*1j*z*theta*sigmanoise/Nt));
interfere= #(gamma1,gamma2,v,z)( ...
(1 -2*c1-c3./(1+2*pi*j*z*theta*v.^(-1))).*(A1.*v.^(delta1-1).* ...
exp(-a1.*v.^(delta1./2))+B1.*v.^(delta2-1).*(1-exp(-b1.*v.^(delta2./2)))));
gscalar=#(gamma1,gamma2,z)integral(#(v)(interfere(gamma1,gamma2,v,z)),gamma2,inf);
g=#(gamma1,gamma2,z)arrayfun(gscalar,gamma1,gamma2,z);
lp=A1*gamma1^(delta1-1)*exp(-a1*gamma1^(delta1/2))+ ...
B1*gamma1^(delta2-1)*(1-exp(-b1*gamma1^(delta2/2)))+ ...
A2*gamma1^(delta1-1)*exp(-a2*gamma1^(delta1/2))+ ...
B2*gamma1^(delta2-1)*(1-exp(-b2*gamma1^(delta2/2)));
dk1=((2*pi*lambda1))/(beta1^2)*(1-exp(-a1*gamma2^(delta1/2))*(1+gamma2^(delta1/2)*a1))+ ...
pi*lambda1*gamma2^(delta2)*p1^delta2- ...
((2*pi*lambda1)/(beta1^2))*(1-exp(-b1*gamma2^(delta2/2))*(1+gamma2^(delta2/2)*b1));
dk2=((2*pi*lambda2))/(beta2^2)*(1-exp(-a2*gamma2^(delta1/2))*(1+gamma2^(delta1/2)*a2))+ ...
pi*lambda2*gamma2^(delta2)*p2^delta2- ...
((2*pi*lambda2)/(beta2^2))*(1-exp(-b2*gamma2^(delta2/2))*(1+gamma2^(delta2/2)*b2));
dk=dk1+dk2;
lcp=A1*gamma2^(delta1-1)*exp(-a1*gamma2^(delta1/2))+ ...
B1*gamma2^(delta2-1)*(1-exp(-b1*gamma2^(delta2/2)))+ ...
A2*gamma2^(delta1-1)*exp(-a2*gamma2^(delta1/2))+ ...
B2*gamma2^(delta2-1)*(1-exp(-b2*gamma2^(delta2/2)));
pdflast=matlabFunction(lp*lcp*exp(-dk));
pdflast=#(gamma1,gamma2)arrayfun(pdflast,gamma1,gamma2);
gamma2min=#(gamma1)gamma1;
T = integral3(#(gamma1,gamma2,z)( ...
laplacenoi(z).*laplacesgi(gamma1,gamma2,z).*pdflast(gamma1,gamma2).*exp(-g(gamma1,gamma2,z))), ...
0,inf,...
#(gamma2)gamma2,inf,...
0.05,1000,...
'abstol',1e-3)
A few notes one this:
MATLAB is one of the languages that require an indication that the logical line should continue after the physical line break. The indication in MATLAB is three dots.
Get rid of any and all warnings the MATLAB editor shows you. In very rare cases, by disabling the warning for this line; usually, by correcting your code. Some of these warnings may seem over-protective, but coe quickly reaches the point where none of us can have enough of it in our minds to see the more subtle problems, and linting helps avoid a fair number of them, in my experience.
Consistent spacing helps, in the same way “proper” (i.e., standardized) spelling makes reading English easier: The patterns are just much more obvious.
Line breaks should in general not be done haphazardly, but emphasizing the structure of commands and formulas. In several of your formulas, I have seen symmetries between input parameters and tried to make them obvious by placing the line breaks accordingly. That helps a lot when looking for typos.
Your code has lines such as these:
pdflast=lp*lcp*exp(-dk);
pdflast=matlabFunction(pdflast);
I used to recycle variables like that, too. Over time, I learned the hard way that it helps for debugging and readability not to, especially if your values have different types, as they do here.
There are a few points I would still clean up at this point. For example, pdflast works just fine on arrays and the line pdflast= #(gamma1,gamma2)arrayfun(pdflast,gamma1,gamma2); should be deleted, and the lower bound for gamma2 in the integral3 call is a function of gamma1 and should be changed to #(gamma1)gamma1.
Does the computer/MATLAB care about any of this? Maybe something slipped in where it does, but basically: No. All of these changes are for you, and if you send your code in an SO post, for us, the readers.
(Likely) Bug: Vectorization
I think your definition of g is wrong:
g=#(gamma1,gamma2,z)arrayfun(gscalar,gamma1,gamma2,z);
The cubature (i.e., integral3) will try to call this function with non-scalar values for one or more of the parameters. Most likely, these will not all be of the same size, and even if they were, it would expect to get a 3D result, not a vector. Try calling your g that way:
>> g(1:2,1,1)
Error using arrayfun
All of the input arguments must be of the same size and shape.
Previous inputs had size 2 in dimension 2. Input #3 has size 1
Error in #(gamma1,gamma2,z)arrayfun(gscalar,gamma1,gamma2,z)
It's really a good idea to check intermediate building blocks like that. What your really need to have is an arrayfun over gamma2, something like this:
gscalar=#(gamma1,gamma2,z) ...
integral(#(v)(interfere(gamma1,gamma2,v,z)),gamma2,inf, ...
'ArrayValued',true);
g = #(gamma1,gamma2,z)arrayfun(#(gamma2)gscalar(gamma1,gamma2,z),gamma2);
(Possible) Bug: Definition of interfere
I don't know if you tried checking interfere against any known or suspected values. (Sanity checks for formulas I just typed seem a really good idea to me.) I somehow doubt that the formula is correctly capturing your intent:
interfere=#(gamma1,gamma2,v,z)( ...
(1-2*c1-c3./(1+2*pi*1j*z*theta*v.^(-1))).*(A1.*v.^(delta1-1).* ...
exp(-a1.*v.^(delta1./2))+B1.*v.^(delta2-1).*(1-exp(-b1.*v.^(delta2./2)))));
The potential problem with this formula (apart from a somewhat inconsistent use of * vs. .* etc.) is that the values do not depend on gamma1 and gamma2 at all.
Of course, that can happen, but if you actually mean it to be the case, what is the rationale for including gamma1 in the formula in the first place?
If this is as it should be, you may need to still make the result the proper size: Right now, interfere simply ignores its first two inputs, which may trip up the integrator: interfere(1:3,1,1,1) should return a 3-element vector.
Concluding Thoughts
As you may have noticed, your question did not get a satisfying answer yet. Nor do I think in its current form it will. To get volunteers to look at your problem, you need to make it easy to understand what you are doing:
Start by simplifying your formulas. They may not be of interest to you anymore, but right now, they're just clutter.
Trim down your parameters. That is somehow part of the above.
Throw out things that are probably irrelevant. Apart from the point that you don't need (and probably don't want) an additional arrayfun around the matlabFunction results, symbolic math is likely to be irrelevant to your actua question on integral3. If you can ask your question without it, it may attract more attention.
For anything you cannot trim down, consider explaining what is happening.
Of course, in this process, for each iteration, test your code (after saying clear all or in a fresh MATLAB session!) to check if the problem is still there. If it is not, you may have found a hint where your basic problem is hiding.
For a longer discussion on the topic, see https://meta.stackexchange.com/questions/18584/how-to-ask-a-smart-question and the guides linked to within that discussion.

Iterative use of bintprog on MATLAB

We have a problem formulation as shown in this link.
Considering that the first call of bintprog gives a solution x that after some post processing does not adequately addresses the physical problem, is it possible to recall bintprog and exclude the prior solution x?
You need a nogood cut.
Suppose you find a solution \hat{x} that you then decide is infeasible (through some sort of post-processing). Let x and \hat{x} be indexed by i.
You can add a constraint of the following form:
\sum_{i : \hat{x}_i = 0} x_i + \sum_{i : \hat{x} = 1} (1-x_i) \geq 1
This constraint is an example of a no-good cut: the solution must differ from \hat{x} by at least one index i, otherwise it is infeasible. If your variables are not binary no-goods can be a little more complex.
You can add a no-good to your solution by appending the constraint as a row to your constraint matrix and re-solving with the bintprog() function. I'll leave it to you to you rewrite it in the MATLAB notation.
You didn't say what your post-processing does, but it would be even better if the post-processing could infer from your solution \hat{x} that other solutions are also infeasible, and you can add more than one row per iteration. This is a form of logic-based Benders decomposition, and the inference of other infeasible solutions is called solving an inference dual (as opposed to standard Benders decomposition, where you're solving the linear programming dual). More on logic based Benders decomposition from the man who coined the term, John Hooker of CMU.
Sorry for the formatting. I need to go but I'll figure out a way to display equations more nicely later.

event location questions in MATLAB

Suppose in matlab the following:
[t, x, te, xe, ie] = ode15s(#myfunc, [tStart tFinal], x0, odeset('Events', #events));
Question 1
1a) The function events is called only after a successful step of the solver. Is this true?
1b) Just after the solver has made a successful step, is it possible that the last call of myfunc not be the call that lead to the successful step?
1c) If the events function contains multiple terminal events and upon a successful step it is detected that two of them (not just one) have occured, what would be the behavior of the solver?
Question 2
Suppose that myfunc contains the following code
if (check(x) > 2)
dx(3) = x(1)*x(2);
else
dx(3) = x(2)^2;
end
where check is some function of x.
One way to solve this problem is not use an events function. In my experience the ode solver can solve such problems that way.
The other way to solve this problem is use an events function to locate check(x) - 2 == 0, one terminal event for direction = 1 and another one for direction = -1. After the solver stops on either of the events a global variable eg myvar is set appropriately to distinguish between the two events, and then the simulation continues from where it stopped. In that case the code in myfunc will be
if (myvar == 1)
dx(3) = x(1)*x(2);
else
dx(3) = x(2)^2;
end
Both way yield correct results in simple cases. However I am trying to solve a very complex problem (additional events than the above and discontinous right-hand parts of the differential equations that are proven to be solvable at some cases) and I am trying to find out if the first way would yield different results than the second one.
One might tell that the ode would either fail to return a solution before tFinal or return a correct solution, but due to the discontinuity of the right-hand part the solver might not return a solution while a solution exists.
So in some sense, the question is: what is the practical-theoretical difference between using the first way and the second way?
Since I've spent some effort on these questions, I'm posting back some feedback.
Question 1
1a) Yes this is true. For reference see for example the ode15s.m matlab solver. However note that before the solver continues solving, the events function may be called several times for the sake of a more accurate te value.
1b) Yes this is also true.
1c) In this case the solver would terminate returning an ie vector containing the two (or even more) indexes of the events that stopped the solver. In that case, the te vector would contain equal elements (te(1) == te(2) will always return true). This is the only way to distiguish "double events" (meaning events that simultaneously stopped the solver after the same successful step) from "fake" events that are recorded when the ode solver continues solving after a terminal event (to understand better what I'm saying also read ode solver event location index in MATLAB ).
Tracing the odezero function will make 1c answer very clear.
Question 2
Now this is a tricky answer. **In general* both ways return correct results. However (and most naturally) they are not bound to return the exact solution points at the exact time points with the exact number of steps.
The notable difference between the two ways is that in the second one, we have a branch change only when a check(x)-2 sign change occurs using only the currently active branch. For example, suppose that the currently active branch is the first one. When the solver notices a sign change in check(x) - 2 after a successful step that was produced using only that branch, only then changes to the second branch. In simple words, both successful and unsuccessful steps are calculated using the very same branch before a use of the other branch can occur. However if we use the first way we may notice a use of the non-active branch during (for example) an unsucessful step.
With these in mind comes the verdict; the most general and strictly correct way to choose is the second one (using events). The first way should also return correct results. HOWEVER, due to the difference between the two ways, the first one could fail in very specific/extreme problems. I'm very tempted to provide information about my case, in which ONLY the second way could be safely used, but it truly is a long way to go.