fvutils / pyvsc

Python packages providing a library for Verification Stimulus and Coverage
https://fvutils.github.io/pyvsc
Apache License 2.0
113 stars 26 forks source link

constraint solver error #189

Closed hanfeng0114 closed 1 year ago

hanfeng0114 commented 1 year ago

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 .

mballance commented 1 year ago

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.