Specman On the Fly Generation:如何约束一个值彼此不同的列表至少为2

时间:2015-08-09 15:03:28

标签: specman

我需要使用下一个约束生成随机列表值:

>>> from email.utils import parsedate_tz, mktime_tz
>>> from datetime import datetime, timedelta
>>> timestamp = mktime_tz(parsedate_tz('Tue May 08 15:14:45 +0800 2012'))
>>> utc_time = datetime(1970, 1, 1) + timedelta(seconds=timestamp)
>>> utc_time
datetime.datetime(2012, 5, 8, 7, 14, 45)

即。列表中的所有值都是不同的,彼此之间至少相差2。我尝试过的所有代码变体都失败了,例如:

my_list[i] not in [my_list[i-1] .. my_list[i-1] + 1]

如何生成此类列表?谢谢你的帮助

2 个答案:

答案 0 :(得分:4)

我不确定我是否完全理解请求,但是请遵循您的代码:

gen my_list keeping {
    it.size() == LIST_SIZE;
    it.all_different(it);
    keep for each (val) in it {
        val != prev;
        val != prev + 1;
    };
};

这将根据您的规则生成一个列表(所有项目将一起生成):

my_list[i] not in [my_list[i-1] .. my_list[i-1] + 1]

但以下列表是一个有效的解决方案:0,2,1,3,5,4,6,8,7,9,11,10,12,... 不遵循"列表中的所有值都是不同的,彼此之间的差异至少为2#。

要根据"文本请求"生成列表,您必须为每个和abs使用double keep:

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;
    };
};

如果您希望对my_list进行排序(并且将更快地解决):

gen my_list keeping {
    it.size() == LIST_SIZE;
    it.size() == LIST_SIZE;
    it.all_different(it);
    for each (val) in it {
        val >= prev + 2;
    };
};

答案 1 :(得分:1)

您可以尝试以下方法:

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];
  };
};

求解器要求约束中的it[index - 1]表达式在生成点处“固定”,因此使用value(...)。这意味着列表将逐个元素生成。

如果这是一个问题,您可以更改为:

    index > 0 => 
       val != it[index - 1] + 1;

这应该是等价的,因为all_different(...)约束应确保元素与前一个元素的值不同。当然,如果您有更广泛的设置,这将无效。