1+ # Licensed to the Apache Software Foundation (ASF) under one
2+ # or more contributor license agreements. See the NOTICE file
3+ # distributed with this work for additional information
4+ # regarding copyright ownership. The ASF licenses this file
5+ # to you under the Apache License, Version 2.0 (the
6+ # "License"); you may not use this file except in compliance
7+ # with the License. You may obtain a copy of the License at
8+ #
9+ # http://www.apache.org/licenses/LICENSE-2.0
10+ #
11+ # Unless required by applicable law or agreed to in writing,
12+ # software distributed under the License is distributed on an
13+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+ # KIND, either express or implied. See the License for the
15+ # specific language governing permissions and limitations
16+ # under the License.
17+
18+
19+ # Created on Jul 28, 2019
20+ #
21+ # @author: ballance
22+
23+ from vsc .model .constraint_model import ConstraintModel
24+ from vsc .model .expr_bin_model import ExprBinModel
25+ from vsc .model .bin_expr_type import BinExprType
26+ from vsc .model .expr_fieldref_model import ExprFieldRefModel
27+ from vsc .model .field_array_model import FieldArrayModel
28+
29+ class ConstraintUniqueVecModel (ConstraintModel ):
30+
31+ def __init__ (self , unique_l ):
32+ super ().__init__ ()
33+ self .unique_l = unique_l
34+ self .expr = None
35+
36+ def build (self , btor , soft = False ):
37+ ret = None
38+
39+ # Elements in the unique list might be arrays
40+ unique_l = []
41+
42+ sz = - 1
43+ for i in self .unique_l :
44+ if sz == - 1 :
45+ sz = len (i .fm .field_l )
46+ elif sz != len (i .fm .field_l ):
47+ raise Exception ("All arguments to unique_vec must be of the same size" )
48+
49+ # Form ORs of inequalities across the vector pairs
50+ and_e = None
51+ for i in range (len (self .unique_l )):
52+ for j in range (i + 1 , len (self .unique_l )):
53+ v_ne = self ._mkVecNotEq (btor , self .unique_l [i ], self .unique_l [j ])
54+
55+ if and_e is None :
56+ and_e = v_ne
57+ else :
58+ and_e = btor .And (and_e , v_ne )
59+
60+ return and_e
61+
62+ def _mkVecNotEq (self , btor , v1 , v2 ):
63+ ret = None
64+ for i in range (len (v1 .fm .field_l )):
65+ ne = ExprBinModel (
66+ ExprFieldRefModel (v1 .fm .field_l [i ]),
67+ BinExprType .Ne ,
68+ ExprFieldRefModel (v2 .fm .field_l [i ]))
69+ if ret is None :
70+ ret = ne .build (btor )
71+ else :
72+ ret = btor .Or (ne .build (btor ), ret )
73+ return ret
74+
75+ def accept (self , visitor ):
76+ visitor .visit_constraint_unique_vec (self )
77+
78+ def clone (self , deep = False )-> 'ConstraintModel' :
79+ ret = ConstraintUniqueVecModel (self .unique_l )
80+
81+ return ret
82+
0 commit comments