fvutils/pyvsc

constraint solver error

Closed this issue · 1 comments

Hi

As #188 said, I tried random sized list:

` def test_group_size(self):
@vsc.randobj
class ThreadGroupConstraintItem():
def init(self, aThreadNum, aSharePercent):
self.mThreadNum = aThreadNum
self.mSharePercent = aSharePercent

            self.mSharePercentGoal = self.mSharePercent
            self.mSharePercentDelta = 10
            self.mSharePercentGoalMin = 0
            self.mSharePercentGoalMax = 0
            self._genSharePrecent()
            self.mSharePercentGoalMinConstr =  vsc.rand_uint16_t(0)
            self.mSharePercentGoalMaxConstr =  vsc.rand_uint16_t(0)
            self.mGroupSize = vsc.rand_uint16_t(0)
            self.GroupList = vsc.randsz_list_t(vsc.rand_uint16_t())
            self.GroupListScore = vsc.randsz_list_t(vsc.rand_uint16_t())
        
        @vsc.constraint
        def basic_c(self):
            self.mGroupSize < self.mThreadNum
            self.mGroupSize > 0
            self.GroupList.size == self.mGroupSize
            self.GroupListScore.size == self.mGroupSize
            # self.GroupListSum == self.GroupList.sum
            # self.GroupList.sum == self.GroupListSum 
            # self.GroupListSum == self.mThreadNum
            with vsc.foreach(self.GroupList, idx=True, it=False) as idx:
                self.GroupList[idx]<= self.mThreadNum
                self.GroupList[idx]>0
            with vsc.foreach(self.GroupList, idx=True, it=False) as idx:
                with vsc.if_then(self.GroupList[idx] > 1):
                    self.GroupListScore[idx] == 1
                with vsc.else_then():
                    self.GroupListScore[idx] == 0
            self.GroupList.sum == self.mThreadNum
            # self.mSharePercentGoalMinConstr == self.mSharePercentGoalMin
            # self.mSharePercentGoalMaxConstr == self.mSharePercentGoalMax
            # self.GroupListScore.sum/self.mGroupSize < int(self.mSharePercentGoalMax/100)
            # self.GroupListScore.sum/self.mGroupSize > int(self.mSharePercentGoalMin/100)

        def _genSharePrecent(self):
            """generate share percent min/max
            """
            if self.mSharePercent > self.mSharePercentDelta:
                self.mSharePercentMin = self.mSharePercent - self.mSharePercentDelta
            else:
                self.mSharePercentMin = 0

            if self.mSharePercent < 100 - self.mSharePercentDelta:
                self.mSharePercentMax = self.mSharePercent + self.mSharePercentDelta
            else:
                self.mSharePercentMax = 100
        

    my_obj_rand = ThreadGroupConstraintItem(8, 80)
    for i in range(10):
        print("Iter %d", i)
        # my_obj_rand.randomize()
        with vsc.randomize_with(my_obj_rand):
            my_obj_rand.GroupList.sum == my_obj_rand.mThreadNum
        print("Thread_num: %0d, GroupList.sum: %d" % (my_obj_rand.mThreadNum, sum(my_obj_rand.GroupList)))
        for i,it in enumerate(my_obj_rand.GroupList):
            print("GroupList[%d]: %d" % (i, it))
            print("GroupListScore[%d]: %d" % (i, my_obj_rand.GroupListScore[i]))

`
The output is not as expected: mThreadNum is 8, but GroupList.sum != mThreadNum:
test_randsz_array.py size: 16
.Iter %d 0
Thread_num: 8, GroupList.sum: 17
GroupList[0]: 1
GroupListScore[0]: 0
GroupList[1]: 5
GroupListScore[1]: 1
GroupList[2]: 8
GroupListScore[2]: 1
GroupList[3]: 1
GroupListScore[3]: 0
GroupList[4]: 2
GroupListScore[4]: 1
Iter %d 1
Thread_num: 8, GroupList.sum: 1
GroupList[0]: 1
GroupListScore[0]: 0
Iter %d 2
Thread_num: 8, GroupList.sum: 8
GroupList[0]: 8
GroupListScore[0]: 1
Iter %d 3
Thread_num: 8, GroupList.sum: 11
GroupList[0]: 8
GroupListScore[0]: 1
GroupList[1]: 3
GroupListScore[1]: 1
Iter %d 4
Thread_num: 8, GroupList.sum: 1
GroupList[0]: 1
GroupListScore[0]: 0
Iter %d 5
Thread_num: 8, GroupList.sum: 30
GroupList[0]: 8
GroupListScore[0]: 1
GroupList[1]: 8
GroupListScore[1]: 1
GroupList[2]: 1
GroupListScore[2]: 0
GroupList[3]: 6
GroupListScore[3]: 1
GroupList[4]: 3
GroupListScore[4]: 1
GroupList[5]: 4
GroupListScore[5]: 1
Iter %d 6
Thread_num: 8, GroupList.sum: 1
GroupList[0]: 1
GroupListScore[0]: 0
Iter %d 7
Thread_num: 8, GroupList.sum: 26
GroupList[0]: 8
GroupListScore[0]: 1
GroupList[1]: 2
GroupListScore[1]: 1
GroupList[2]: 4
GroupListScore[2]: 1
GroupList[3]: 6
GroupListScore[3]: 1
GroupList[4]: 6
GroupListScore[4]: 1
Iter %d 8
Thread_num: 8, GroupList.sum: 2
GroupList[0]: 2
GroupListScore[0]: 1
Iter %d 9
Thread_num: 8, GroupList.sum: 33
GroupList[0]: 8
GroupListScore[0]: 1
GroupList[1]: 3
GroupListScore[1]: 1
GroupList[2]: 1
GroupListScore[2]: 0
GroupList[3]: 8
GroupListScore[3]: 1
GroupList[4]: 8
GroupListScore[4]: 1
GroupList[5]: 5
GroupListScore[5]: 1
.Size: 4
.

Thanks, the testcase is very helpful. After investigating, it seems that constraints involving array sum were not being properly grouped for solving. Specifically, the sum constraint wasn't causing all array elements to be solved together. The 0.8.5 release contains a fix that allows this testcase to pass.