11using Semgus . Model . Smt . Terms ;
22using Semgus . Model . Smt . Theories ;
3-
3+ using System . Collections ;
44using System . Diagnostics . CodeAnalysis ;
55
66namespace Semgus . Model . Smt . Extensions
@@ -63,6 +63,7 @@ public bool TryGetSort(SmtSortIdentifier sortId, [NotNullWhen(true)] out SmtSort
6363 internal SmtBitVectorsExtension ( SmtCoreTheory core , SmtBitVectorsTheory bv )
6464 {
6565 var bv0 = new SmtSort . WildcardSort ( new ( new SmtIdentifier ( "BitVec" , "*" ) ) ) ;
66+ var bool0 = core . Sorts [ SmtCommonIdentifiers . BoolSortId . Name ] ;
6667 SmtSourceBuilder sb = new ( this ) ;
6768 sb . AddFn ( name : "bvxor" ,
6869 val : SmtSourceBuilder . CheckArgumentSortsEqual ,
@@ -88,12 +89,164 @@ internal SmtBitVectorsExtension(SmtCoreTheory core, SmtBitVectorsTheory bv)
8889 var a2 = new SmtVariable ( a2_id , a2_binding ! ) ;
8990
9091 var b = new SmtTermBuilder ( ctx ) ;
92+ // (xor a1 a2) = (bvor (bvand a1 (bvnot a2)) (bvand (not a1) a2))
9193 return b . Lambda ( scope ,
9294 b . Apply ( bvor_id , b . Apply ( bvand_id , a1 , b . Apply ( bvnot_id , a2 ) ) ,
9395 b . Apply ( bvand_id , b . Apply ( bvnot_id , a1 ) , a2 ) ) ) ;
9496
9597 } ) ;
9698
99+ sb . AddFn ( name : "bvugt" ,
100+ val : SmtSourceBuilder . CheckArgumentSortsEqual ,
101+ valCmt : "Argument sorts must be the same" ,
102+ retCalc : SmtSourceBuilder . UseReturnSort ,
103+ bool0 ,
104+ bv0 ,
105+ bv0 )
106+ . DefinitionMissing ( ( ctx , fn , rank ) =>
107+ {
108+ SmtIdentifier bvult_id = new ( "bvult" ) ;
109+
110+ var a1_id = new SmtIdentifier ( "a1" ) ;
111+ var a2_id = new SmtIdentifier ( "a2" ) ;
112+
113+ SmtScope scope = new ( default ) ;
114+ scope . TryAddVariableBinding ( a1_id , rank . ArgumentSorts [ 0 ] , SmtVariableBindingType . Lambda , ctx , out var a1_binding , out _ ) ;
115+ scope . TryAddVariableBinding ( a2_id , rank . ArgumentSorts [ 1 ] , SmtVariableBindingType . Lambda , ctx , out var a2_binding , out _ ) ;
116+
117+ var a1 = new SmtVariable ( a1_id , a1_binding ! ) ;
118+ var a2 = new SmtVariable ( a2_id , a2_binding ! ) ;
119+
120+ var b = new SmtTermBuilder ( ctx ) ;
121+ // (bvugt a1 a2) = (bvult a2 a1)
122+ return b . Lambda ( scope ,
123+ b . Apply ( bvult_id , a2 , a1 ) ) ;
124+
125+ } ) ;
126+
127+ sb . AddFn ( name : "bvule" ,
128+ val : SmtSourceBuilder . CheckArgumentSortsEqual ,
129+ valCmt : "Argument sorts must be the same" ,
130+ retCalc : SmtSourceBuilder . UseReturnSort ,
131+ ret : bool0 ,
132+ bv0 ,
133+ bv0 )
134+ . DefinitionMissing ( ( ctx , fn , rank ) =>
135+ {
136+ SmtIdentifier bvult_id = new ( "bvult" ) ;
137+ SmtIdentifier eq_id = new ( "=" ) ;
138+ SmtIdentifier or_id = new ( "or" ) ;
139+
140+ var a1_id = new SmtIdentifier ( "a1" ) ;
141+ var a2_id = new SmtIdentifier ( "a2" ) ;
142+
143+ SmtScope scope = new ( default ) ;
144+ scope . TryAddVariableBinding ( a1_id , rank . ArgumentSorts [ 0 ] , SmtVariableBindingType . Lambda , ctx , out var a1_binding , out _ ) ;
145+ scope . TryAddVariableBinding ( a2_id , rank . ArgumentSorts [ 1 ] , SmtVariableBindingType . Lambda , ctx , out var a2_binding , out _ ) ;
146+
147+ var a1 = new SmtVariable ( a1_id , a1_binding ! ) ;
148+ var a2 = new SmtVariable ( a2_id , a2_binding ! ) ;
149+
150+ var b = new SmtTermBuilder ( ctx ) ;
151+ // (bvule a1 a2) = (or (bvult a1 a2) (= a1 a2))
152+ return b . Lambda ( scope ,
153+ b . Apply ( or_id ,
154+ b . Apply ( bvult_id , a1 , a2 ) ,
155+ b . Apply ( eq_id , a1 , a2 ) ) ) ;
156+
157+ } ) ;
158+
159+ sb . AddFn ( name : "bvuge" ,
160+ val : SmtSourceBuilder . CheckArgumentSortsEqual ,
161+ valCmt : "Argument sorts must be the same" ,
162+ retCalc : SmtSourceBuilder . UseReturnSort ,
163+ bool0 ,
164+ bv0 ,
165+ bv0 )
166+ . DefinitionMissing ( ( ctx , fn , rank ) =>
167+ {
168+ SmtIdentifier bvult_id = new ( "bvult" ) ;
169+ SmtIdentifier eq_id = new ( "=" ) ;
170+ SmtIdentifier or_id = new ( "or" ) ;
171+
172+ var a1_id = new SmtIdentifier ( "a1" ) ;
173+ var a2_id = new SmtIdentifier ( "a2" ) ;
174+
175+ SmtScope scope = new ( default ) ;
176+ scope . TryAddVariableBinding ( a1_id , rank . ArgumentSorts [ 0 ] , SmtVariableBindingType . Lambda , ctx , out var a1_binding , out _ ) ;
177+ scope . TryAddVariableBinding ( a2_id , rank . ArgumentSorts [ 1 ] , SmtVariableBindingType . Lambda , ctx , out var a2_binding , out _ ) ;
178+
179+ var a1 = new SmtVariable ( a1_id , a1_binding ! ) ;
180+ var a2 = new SmtVariable ( a2_id , a2_binding ! ) ;
181+
182+ var b = new SmtTermBuilder ( ctx ) ;
183+ // (bvuge a1 a2) = (or (bvult a2 a1) (= a1 a2))
184+ return b . Lambda ( scope ,
185+ b . Apply ( or_id ,
186+ b . Apply ( bvult_id , a2 , a1 ) ,
187+ b . Apply ( eq_id , a1 , a2 ) ) ) ;
188+
189+ } ) ;
190+
191+ sb . AddFn ( name : "bveq" ,
192+ val : SmtSourceBuilder . CheckArgumentSortsEqual ,
193+ valCmt : "Argument sorts must be the same" ,
194+ retCalc : SmtSourceBuilder . UseReturnSort ,
195+ bool0 ,
196+ bv0 ,
197+ bv0 )
198+ . DefinitionMissing ( ( ctx , fn , rank ) =>
199+ {
200+ SmtIdentifier bveq_id = new ( "=" ) ;
201+
202+ var a1_id = new SmtIdentifier ( "a1" ) ;
203+ var a2_id = new SmtIdentifier ( "a2" ) ;
204+
205+ SmtScope scope = new ( default ) ;
206+ scope . TryAddVariableBinding ( a1_id , rank . ArgumentSorts [ 0 ] , SmtVariableBindingType . Lambda , ctx , out var a1_binding , out _ ) ;
207+ scope . TryAddVariableBinding ( a2_id , rank . ArgumentSorts [ 1 ] , SmtVariableBindingType . Lambda , ctx , out var a2_binding , out _ ) ;
208+
209+ var a1 = new SmtVariable ( a1_id , a1_binding ! ) ;
210+ var a2 = new SmtVariable ( a2_id , a2_binding ! ) ;
211+
212+ var b = new SmtTermBuilder ( ctx ) ;
213+ // (bvueq a1 a2) = (= a1 a2)
214+ return b . Lambda ( scope , b . Apply ( bveq_id , a1 , a2 ) ) ;
215+
216+ } ) ;
217+
218+ sb . AddFn ( name : "bvsub" ,
219+ val : SmtSourceBuilder . CheckArgumentSortsEqual ,
220+ valCmt : "Argument sorts must be of the same size" ,
221+ retCalc : SmtSourceBuilder . UseFirstArgumentSort ,
222+ bv0 ,
223+ bv0 ,
224+ bv0 )
225+ . DefinitionMissing ( ( ctx , fn , rank ) =>
226+ {
227+ SmtIdentifier bvadd_id = new ( "bvadd" ) ;
228+ SmtIdentifier bvnot_id = new ( "bvnot" ) ;
229+
230+ var a1_id = new SmtIdentifier ( "a1" ) ;
231+ var a2_id = new SmtIdentifier ( "a2" ) ;
232+ var c1_id = new SmtIdentifier ( "c1" ) ;
233+
234+ SmtScope scope = new ( default ) ;
235+ scope . TryAddVariableBinding ( a1_id , rank . ArgumentSorts [ 0 ] , SmtVariableBindingType . Lambda , ctx , out var a1_binding , out _ ) ;
236+ scope . TryAddVariableBinding ( a2_id , rank . ArgumentSorts [ 1 ] , SmtVariableBindingType . Lambda , ctx , out var a2_binding , out _ ) ;
237+
238+ var a1 = new SmtVariable ( a1_id , a1_binding ! ) ;
239+ var a2 = new SmtVariable ( a2_id , a2_binding ! ) ;
240+ var c1 = new SmtBitVectorLiteral ( ctx , new BitArray ( new int [ ] { 1 } ) ) ;
241+
242+ var b = new SmtTermBuilder ( ctx ) ;
243+ // 2's complement
244+ return b . Lambda ( scope ,
245+ b . Apply ( bvadd_id , b . Apply ( bvadd_id , a1 , b . Apply ( bvnot_id , a2 ) ) ,
246+ c1 ) ) ;
247+
248+ } ) ;
249+
97250 Functions = sb . Functions ;
98251 PrimaryFunctionSymbols = sb . PrimaryFunctionSymbols ;
99252 }
0 commit comments