How to write functions that handle in-line constraints

Hello All,

I have a class, where for each value of variable1, only few of the possible values of other variables are valid.
In other words, I have too many illegal combinations to constraint and few valid combinations.

I fear writing too many constraints will slowdown the constraint solver, is my assumption valid?
I thought of implementing the above by populate the queue with the valid combinations and based on user inputs, I search the queue for valid objects and return a valid one, instead of randomizing with too may constraints.

The same class has few other variables that can be randomized and above method will not work as there are too many valid combinations.

For that I need to implement a function say “pseudo_randomize” that can take two “with clauses” that contain an expression for “find_index” and an “in-line constraint” block.

But I am not sure how to implement a function that can do so.

Function call should look something like below.

pseudo_randomize() with_find {} with_constraints {};

or

pseudo_randomize({expression_for_search}, {constraints_to_randomize});

Any out of the box solutions to solve above are also welcome.


Thanks & Regards,
Krishna

Constraint solvers are actually very good dealing with many constraints and you don’t want to re-invent your own solver. There are a few cases where this may not be true, but it is hard to answer your questions without seeing some examples of the kinds of constraints you need. You may want to look at the inside operator’s ability to search an array for a match.

In reply to dave_59:

Hi Dave,

Sorry for the delay. And thanks for the quick response.

Here is the sample code…


  // Types
  typedef enum {A0, A1, A2, A3, A4, A5, A6, A7, A8, A9} type_a;
  typedef enum {B0, B1, B2, B3, B4, B5, B6, B7, B8, B9} type_b;
  typedef enum {C0, C1, C2, C3, C4, C5, C6, C7, C8, C9} type_c;

  // Single element
  class myClass;
    const type_a a;
    const type_b b;
    const type_c c;

    // Some random variables based on contant fields
    rand int ar;
    rand int br;
    rand int cr;

    // Constraints linking constant fields with random variables
    constraint dummy_constraint {
      if (a == A0) ar == 'd10;
      if (b == B1) ar == 'd13;
      if (c == C2) ar == 'd20;
    }

    // Initializes constant fields
    function new (type_a a, type_b b, type_c c);
      this.a = a;
      this.b = b;
      this.c = c;
    endfunction : new

    // Show method
    function void show;
      $display (a.name, " ", b.name, " ", c.name);
    endfunction : show
  endclass : myClass

As you see, we can have 10^3 possible combinations for variables a, b & c together, but out of them very few are actually valid, (10 in our case) enumerated below.


  // Container of queue
  class db_manager;
    const local myClass q[$];
    local myClass tmp;

    function new;
      myClass q[$];
      tmp = new(A0, B0, C0);  q.push_back(tmp);
      tmp = new(A1, B2, C1);  q.push_back(tmp);
      tmp = new(A2, B4, C3);  q.push_back(tmp);
      tmp = new(A3, B6, C5);  q.push_back(tmp);
      tmp = new(A4, B8, C7);  q.push_back(tmp);
      tmp = new(A5, B1, C9);  q.push_back(tmp);
      tmp = new(A6, B3, C2);  q.push_back(tmp);
      tmp = new(A7, B5, C4);  q.push_back(tmp);
      tmp = new(A8, B7, C6);  q.push_back(tmp);
      tmp = new(A9, B9, C8);  q.push_back(tmp);

      this.q = q;
    endfunction

    function show;
      foreach (q[i]) q[i].show();
    endfunction : show
  endclass : db_manager

In my case, its about few thousand valid combinations in a pool of few million possible combinations.
On top of that, I will have few random variables like ‘ar, br & cr’, that depend on ‘a, b & c’, which will have more constraints.

Hence my requirement, to search the queue with given search criteria among constant fields, and then to randomize the random fields.

Please let me know if you need any further inputs.
This time I will respond soon.


Regards,
Krishna

In reply to VijayaKrishnaKasula:

This is not really clear enough. Can you give a few examples of the data you expect to produce? And how do you plan on calling randomize()?

In reply to dave_59:

Hi Dave,

I need to implement a function in db_manager something like below


function myClass db_manager::getRandomItem (
  input expression_type find_clause,  // Operates only on const fields of myClass
  input expression_type constraints   // Operates only on random fields of myClass
);

myClass obj;
int matching_idxs[$];

matching_idxs = q.find_index () with (find_clause);
noMatchingElements: assert (matching_idxs.size() > 0) else $fatal ("No matching elements found");

// Take a copy of matching item
obj = q[matching_idxs[$urandom_range(matching_idxs.size() - 1)]].copy()

constraintFaulire:  assert (obj.randomize() with constraints) else $fatal (
"Randomizing failed at line", `__LINE__
);

return obj;

endfunction : getRandomItem

and call it from somewhere as below


initial begin
  myClass obj;
  db_manager db;

  obj = db.getRandomItem (
    // find_clause
    (
      (item.a inside {A0, A1, A2}) &&
      (item.b inside {B0, B1, B2})
    ),
    // constraints
    (
      ar inside {['d0:'d20]};
      br inside {['d0:'d20]};
    )
  );
end

Sample output (3 iterations)…


a   b   c   ar    br    cr
A0  B1  C5  'd10  'd13  'd89
A1  B1  C9  'd19  'd13  'd48
A2  B2  C2  'd11  'd10  'd20

In reply to VijayaKrishnaKasula:

You can’t pass an expression as an argument to a function, you can only pass the value that is the result of that expression.

If your constraint expression are fixed (which I suspect they are not), you can still pass the values used by the expression through the function arguments. Probably a better option is to use inheritance and provide overrides for the functions you need. You can do this on the object as a whole, or create policy classes for each specific aspect that you want to override.

Without knowing all your requirements of what you are trying to accomplish it’s going to be difficult to suggest an approach to use, and that might be too complex to discuss in this forum. I suggest trying to get someone locally with some experience to help you out.