pyvsc icon indicating copy to clipboard operation
pyvsc copied to clipboard

Support updating the definition of rangelists

Open mballance opened this issue 4 years ago • 2 comments

@mballance,

I have created randobj's that store rangelist values in their properties. These properties are then used in constraints. My problem is that updating the value of a rangelist-holding property to a new rangelist has no effect. Constraints seem to remember only the initial rangelist that is stored in a property.

The example below illustrates the problem. The Selector.available property is initialized to vsc.rangelist((0, 999)), and is used in a constraint. Randomize() produces a stream of 10 integers in the range [0..999]. Then Selector.available is changed to vsc.rangelist((1000, 1999)) and randomize() is called again, but the next 10 integers are still in the range [0..999], not [1000..1999].

Is this expected? Is there a good workaround? I realize that instead of being a rangelist, Selector.available could be of type list_t. However, this would lose the efficiency representing large sets of contiguous integers in a rangelist.

import vsc

@vsc.randobj
class Selector:
    def __init__(self):
        self.available = vsc.rangelist((0, 999))
        self.selected = vsc.rand_uint64_t()

    @vsc.constraint
    def max_c(self):
        self.selected.inside(self.available)

selector = Selector()
outStr = "A:"
for i in range(10):
    selector.randomize()
    outStr += "\t" + str(selector.selected)
print(outStr)

# Change the range that numbers are selected from.
selector.available = vsc.rangelist((1000, 1999))

outStr = "B:"
for i in range(10):
    selector.randomize()
    outStr += "\t" + str(selector.selected)
print(outStr)
A:      459     280     90      114     442     833     335     965     762     287
B:      413     966     921     486     733     688     285     999     864     886

Originally posted by @msmftc in https://github.com/fvutils/pyvsc/discussions/126

mballance avatar Nov 12 '21 21:11 mballance

Hi @msmftc, I've implemented support for modifying rangelists in release 0.6.4. Here's a test showing off a couple of the new methods (clear, append, extend) on rangelist: https://github.com/fvutils/pyvsc/blob/dd5405e52a32b8a3a744fa67a33dbf34c09143c2/ve/unit/test_constraint_rangelist.py#L50-L97

mballance avatar Nov 20 '21 01:11 mballance

@mballance,

Thank-you for this feature. I've tested it and it meets my needs. However, there is a corner case problem that ought to be fixed for more general use.

Initializing an empty rangelist, as in self.available = vsc.rangelist(), raises the error "Empty rangelist specified" - but an empty rangelist can still be created with a sequence like this:

self.available = vsc.rangelist(0)
self.available.clear()

It can be handy to have empty rangelists, so I'd prefer that the "Empty rangelist specified" error be removed, since it doesn't prevent empty rangelists anyway. This would require different handling of empty rangelists in constraints. Right now, using an empty rangelist in a constraint raises the error "TypeError: 'NoneType' object is not subscriptable." If that error could be replaced with a SolveError then empty rangelists would generally behave the way that users expect.

Better yet would be proper handling of expressions like self.number.not_inside(vsc.rangelist()), which logically ought to be true, but this is a low priority.

msmftc avatar Nov 28 '21 05:11 msmftc