Specman on-the-fly generation for multiple constrained items - specman

I have this multiple fields that need to be constrained in this manner:
struct my_struct {
a : uint;
b : uint;
c : uint;
d : uint;
keep 3*a + 4*b + 5*c + 6*d == 206 and a + b + c + d == 50;
my_method() #clk_event is {
while (TRUE) {
if (ctr == 0) {
gen a;
gen b;
gen c;
gen d;
};
if (ctr == 50) {
ctr = 0;
} else {
ctr += 1;
};
wait cycle;
};
};
};
I basically want to generate a new set of values for a, b, c, and d periodically. The above code is not working as their values did not change in my simulation. Any idea how to do it?

When you generate one field, other fields can't change their values, they are inputs for the constraints. Given your constraints, there can be only one correct value for a field if three other can't change.
You probably need to modify the design and put the fields with constraints under a struct, and have a field of this struct type. So instead of four separate gens, you will have only one, and it will do the job right.

Related

Minimum cost solution to connect all elements in set A to at least one element in set B

I need to find the shortest set of paths to connect each element of Set A with at least one element of Set B. Repetitions in A OR B are allowed (but not both), and no element can be left unconnected. Something like this:
I'm representing the elements as integers, so the "cost" of a connection is just the absolute value of the difference. I also have a cost for crossing paths, so if Set A = [60, 64] and Set B = [63, 67], then (60 -> 67) incurs an additional cost. There can be any number of elements in either set.
I've calculated the table of transitions and costs (distances and crossings), but I can't find the algorithm to find the lowest-cost solution. I keep ending up with either too many connections (i.e., repetitions in both A and B) or greedy solutions that omit elements (e.g., when A and B are non-overlapping). I haven't been able to find examples of precisely this kind of problem online, so I hoped someone here might be able to help, or at least point me in the right direction. I'm not a graph theorist (obviously!), and I'm writing in Swift, so code examples in Swift (or pseudocode) would be much appreciated.
UPDATE: The solution offered by #Daniel is almost working, but it does occasionally add unnecessary duplicates. I think this may be something to do with the sorting of the priorityQueue -- the duplicates always involve identical elements with identical costs. My first thought was to add some kind of "positional encoding" (yes, Transformer-speak) to the costs, so that the costs are offset by their positions (though of course, this doesn't guarantee unique costs). I thought I'd post my Swift version here, in case anyone has any ideas:
public static func voiceLeading(from chA: [Int], to chB: [Int]) -> Set<[Int]> {
var result: Set<[Int]> = Set()
let im = intervalMatrix(chA, chB: chB)
if im.count == 0 { return [[0]] }
let vc = voiceCrossingCostsMatrix(chA, chB: chB, cost: 4)
// NOTE: cm contains the weights
let cm = VectorUtils.absoluteAddMatrix(im, toMatrix: vc)
var A_links: [Int:Int] = [:]
var B_links: [Int:Int] = [:]
var priorityQueue: [Entry] = []
for (i, a) in chA.enumerated() {
for (j, b) in chB.enumerated() {
priorityQueue.append(Entry(a: a, b: b, cost: cm[i][j]))
if A_links[a] != nil {
A_links[a]! += 1
} else {
A_links[a] = 1
}
if B_links[b] != nil {
B_links[b]! += 1
} else {
B_links[b] = 1
}
}
}
priorityQueue.sort { $0.cost > $1.cost }
while priorityQueue.count > 0 {
let entry = priorityQueue[0]
if A_links[entry.a]! > 1 && B_links[entry.b]! > 1 {
A_links[entry.a]! -= 1
B_links[entry.b]! -= 1
} else {
result.insert([entry.a, (entry.b - entry.a)])
}
priorityQueue.remove(at: 0)
}
return result
}
Of course, since the duplicates have identical scores, it shouldn't be a problem to just remove the extras, but it feels a bit hackish...
UPDATE 2: Slightly less hackish (but still a bit!); since the requirement is that my result should have equal cardinality to max(|A|, |B|), I can actually just stop adding entries to my result when I've reached the target cardinality. Seems okay...
UPDATE 3: Resurrecting this old question, I've recently had some problems arise from the fact that the above algorithm doesn't fulfill my requirement |S| == max(|A|, |B|) (where S is the set of pairings). If anyone knows of a simple way of ensuring this it would be much appreciated. (I'll obviously be poking away at possible changes.)
This is an easy task:
Add all edges of the graph in a priority_queue, where the biggest priority is the edge with the biggest weight.
Look each edge e = (u, v, w) in the priority_queue, where u is in A, v is in B and w is the weight.
If removing e from the graph doesn't leave u or v isolated, remove it.
Otherwise, e is part of the answer.
This should be enough for your case:
#include <bits/stdc++.h>
using namespace std;
struct edge {
int u, v, w;
edge(){}
edge(int up, int vp, int wp){u = up; v = vp; w = wp;}
void print(){ cout<<"("<<u<<", "<<v<<")"<<endl; }
bool operator<(const edge& rhs) const {return w < rhs.w;}
};
vector<edge> E; //edge set
priority_queue<edge> pq;
vector<edge> ans;
int grade[5] = {3, 3, 2, 2, 2};
int main(){
E.push_back(edge(0, 2, 1)); E.push_back(edge(0, 3, 1)); E.push_back(edge(0, 4, 4));
E.push_back(edge(1, 2, 5)); E.push_back(edge(1, 3, 2)); E.push_back(edge(1, 4, 0));
for(int i = 0; i < E.size(); i++) pq.push(E[i]);
while(!pq.empty()){
edge e = pq.top();
if(grade[e.u] > 1 && grade[e.v] > 1){
grade[e.u]--; grade[e.v]--;
}
else ans.push_back(e);
pq.pop();
}
for(int i = 0; i < ans.size(); i++) ans[i].print();
return 0;
}
Complexity: O(E lg(E)).
I think this problem is "minimum weighted bipartite matching" (although searching for " maximum weighted bipartite matching" would also be relevant, it's just the opposite)

How to generate a model for my code using boolector?

I'm experimenting a bit with boolector so I'm trying to create model for simple code. Suppose that I have the following pseudo code:
int a = 5;
int b = 4;
int c = 3;
For this simple set of instructions I can create the model and all works fine. The problem is when I have other instructions after that like
b = 10;
c = 20;
Obviously it fails to generate the model because b cannot be equal to 4 and 10 within the same module. One of the maintainer suggested me to use boolector_push and boolector_pop in order to create new Contexts when needed.
The code for boolector_push is :
void
boolector_push (Btor *btor, uint32_t level)
{
BTOR_ABORT_ARG_NULL (btor);
BTOR_TRAPI ("%u", level);
BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
"incremental usage has not been enabled");
if (level == 0) return;
uint32_t i;
for (i = 0; i < level; i++)
{
BTOR_PUSH_STACK (btor->assertions_trail,
BTOR_COUNT_STACK (btor->assertions));
}
btor->num_push_pop++;
}
Instead for boolector_pop is
void
boolector_pop (Btor *btor, uint32_t level)
{
BTOR_ABORT_ARG_NULL (btor);
BTOR_TRAPI ("%u", level);
BTOR_ABORT (!btor_opt_get (btor, BTOR_OPT_INCREMENTAL),
"incremental usage has not been enabled");
BTOR_ABORT (level > BTOR_COUNT_STACK (btor->assertions_trail),
"can not pop more levels (%u) than created via push (%u).",
level,
BTOR_COUNT_STACK (btor->assertions_trail));
if (level == 0) return;
uint32_t i, pos;
BtorNode *cur;
for (i = 0, pos = 0; i < level; i++)
pos = BTOR_POP_STACK (btor->assertions_trail);
while (BTOR_COUNT_STACK (btor->assertions) > pos)
{
cur = BTOR_POP_STACK (btor->assertions);
btor_hashint_table_remove (btor->assertions_cache, btor_node_get_id (cur));
btor_node_release (btor, cur);
}
btor->num_push_pop++;
}
In my opinion, those 2 functions maintains track of the assertions generated using boolector_assert so how is it possible to obtain the final and correct model using boolector_push and boolector_pop considering that the constraints are going to be the same?
What am I missing?
Thanks
As you suspected, solver's push and pop methods aren't what you're looking for here. Instead, you have to turn the program you are modeling into what's known as SSA (Static Single Assignment) form. Here's the wikipedia article on it, which is quite informative: https://en.wikipedia.org/wiki/Static_single_assignment_form
The basic idea is that you "treat" your mutable variables as time-varying values, and give them unique names as you make multiple assignments to them. So, the following:
a = 5
b = a + 2
c = b + 3
c = c + 1
b = c + 6
becomes:
a0 = 5
b0 = a0 + 2
c0 = b0 + 3
c1 = c0 + 1
b1 = c1 + 6
etc. Note that conditionals are tricky to deal with, and generally require what's known as phi-nodes. (i.e., merging the values of branches.) Most compilers do this sort of conversion automatically for you, as it enables many optimizations down the road. You can either do it by hand, or use an algorithm to do it for you, depending on your particular problem.
Here's another question on stack-overflow, that's essentially asking for something similar: Z3 Conditional Statement
Hope this helps!

Specman On the Fly Generation: How to constrain a list whose values are differ from each other at least 2

I need to generate a random list values with the next constrain:
my_list[i] not in [my_list[i-1] .. my_list[i-1] + 1]
i.e. all values in the list are different and with at least difference of 2 between each other. All code variations I've tried failed, e.g.:
var prev_val : uint = 0;
gen my_list keeping {
it.size() == LIST_SIZE;
it.all_different(it);
for each (val) in it {
val not in [prev_val .. prev_val + 1];
prev_val = val;
};
};
How such list can be generated? Thank you for your help
I am not sure I fully understand the request but following your code:
gen my_list keeping {
it.size() == LIST_SIZE;
it.all_different(it);
keep for each (val) in it {
val != prev;
val != prev + 1;
};
};
This will generate a list (all items will be generate together) according to your rule:
my_list[i] not in [my_list[i-1] .. my_list[i-1] + 1]
But the following list is a valid solution: 0,2,1,3,5,4,6,8,7,9,11,10,12,...
which doesn't follow "the all values in the list are different and with at least difference of 2 between each other".
To generate a list according to the "text request", you must use double keep for each and abs:
gen my_list keeping {
it.size() == LIST_SIZE;
for each (val1) using index (i1) in it {
for each (val2) using index (i2) in it {
i1 < i2 => abs(val1-val2) >= 2;
};
};
If you want my_list to be sorted (and will be solved faster) :
gen my_list keeping {
it.size() == LIST_SIZE;
it.size() == LIST_SIZE;
it.all_different(it);
for each (val) in it {
val >= prev + 2;
};
};
You could try the following:
gen my_list keeping {
it.size() == 10;
it.all_different(it);
for each (val) in it {
index > 0 =>
val not in [value(it[index - 1]) .. value(it[index - 1]) + 1];
};
};
The solver requires the it[index - 1] expression in the constraint be "fixed" at the point of generation, hence the use of value(...). This means that the list will be generated element by element.
If that's a problem, you could change to:
index > 0 =>
val != it[index - 1] + 1;
This should be equivalent, since the all_different(...) constraint should make sure that an element doesn't have the same value as the previous one. Naturally, this won't work if you have a wider set.

Printing the values from the corresponding array

Suppose:
1 A
2 B
3 C
I need to print the value corresponding to 1-> A. I have put each in an array:
d1[1,2,3] and s1[A,B,C]. Now I need to print the value in the form shown in the above:
d1[0] s1[0]
1 A
How can I do this using UnityScript? In the program, I did id printing in this format:
1 A
1 B
1 C
2 A
2 B
2 C
What you have probably done, and I'm guessing without seeing the code is something along that you have a for loop within a for loop which means you're processing the first item in the first array and then all items in the second:
for (var i = 0; i < d1.Length; i++) {
for(var j = 0; j < s1.length; j++ {
Debug.log(d1[i] + " " + s1[j])
}
}
Your options depend on the array sizes and how you want to handle them. For example if you know they're the same size consistently then
for(var i = 0; i < d1.Length; i++) {
Debug.log(d1[i] + " " + s1[i])
}
should work. I would wonder if what you're trying to achieve could be done with a different data structure such as a dictionary, etc.

cula use of culaSgels - wrong argument?

I am trying to use the culaSgels function in order to solve Ax=B.
I modified the systemSolve example of the cula package.
void culaFloatExample()
{
int N=2;
int NRHS = 2;
int i,j;
double cula_time,start_time,end_time;
culaStatus status;
culaFloat* A = NULL;
culaFloat* B = NULL;
culaFloat* X = NULL;
culaFloat one = 1.0f;
culaFloat thresh = 1e-6f;
culaFloat diff;
printf("Allocating Matrices\n");
A = (culaFloat*)malloc(N*N*sizeof(culaFloat));
B = (culaFloat*)malloc(N*N*sizeof(culaFloat));
X = (culaFloat*)malloc(N*N*sizeof(culaFloat));
if(!A || !B )
exit(EXIT_FAILURE);
printf("Initializing CULA\n");
status = culaInitialize();
checkStatus(status);
// Set A
A[0]=1;
A[1]=2;
A[2]=3;
A[3]=4;
// Set B
B[0]=5;
B[1]=6;
B[2]=2;
B[3]=3;
printf("Calling culaSgels\n");
// Run CULA's version
start_time = getHighResolutionTime();
status = culaSgels('N',N,N, NRHS, A, N, A, N);
end_time = getHighResolutionTime();
cula_time = end_time - start_time;
checkStatus(status);
printf("Verifying Result\n");
for(i = 0; i < N; ++i){
for (j=0;j<N;j++)
{
diff = X[i+j*N] - B[i+j*N];
if(diff < 0.0f)
diff = -diff;
if(diff > thresh)
printf("\nResult check failed: X[%d]=%f B[%d]=%f\n", i, X[i+j*N],i, B[i+j*N]);
printf("\nResults:X= %f \t B= %f:\n",X[i+j*N],B[i+j*N]);
}
}
printRuntime(cula_time);
printf("Shutting down CULA\n\n");
culaShutdown();
free(A);
free(B);
}
I am using culaSgels('N',N,N, NRHS, A, N, A, N); to solve the system but :
1) The results show me that every element of X=0 , but B is right.
Also , it shows me the
Result check failed message
2) Studying the reference manual ,it says that one argument before the last argument (the A I have) ,should be the matrix B stored columnwised,but if I use "B" instead of "A" as parameter ,then I am not getting the correct B matrix.
Ok,code needs 3 things to work.
1) Change A to B ,so culaSgels('N',N,N, NRHS, A, N, B, N);
(I misunderstood that at exit B contains the solution)
2) Because CULA uses column major change A,B matrices accordingly.
3) Change to :
B = (culaFloat*)malloc(N*NRHS*sizeof(culaFloat));
X = (culaFloat*)malloc(N*NRHS*sizeof(culaFloat));
(use NHRS and not N which is the same in this example)
Thanks!