Skip to content

Commit 94d1c5b

Browse files
committed
vector operations helper and git link
1 parent f264f66 commit 94d1c5b

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<img src="https://raw.githubusercontent.com/philzook58/knuckledragger/main/docs/logo.webp" alt="drawing" width="200" align="left"/>
44

5-
Knuckledragger is an attempt at creating a down to earth, highly automated interactive proof assistant in python. The goal is to support applications like software/hardware verification, calculus, equational reasoning, and numerical bounds.
5+
Knuckledragger ([git repo](https://github.com/philzook58/knuckledragger)) is an attempt at creating a down to earth, highly automated interactive proof assistant in python. The goal is to support applications like software/hardware verification, calculus, equational reasoning, and numerical bounds.
66

77
<br clear="left"/>
88

src/kdrag/theories/bitvec.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,3 +319,42 @@ def PopCount(x: smt.BitVecRef) -> smt.ArithRef:
319319
2
320320
"""
321321
return smt.Sum([smt.BV2Int(smt.Extract(i, i, x)) for i in range(x.size())])
322+
323+
324+
def UnConcat(x: smt.BitVecRef, lane_num: int) -> list[smt.BitVecRef]:
325+
"""
326+
Unpack a bitvector into lanes.
327+
328+
>>> x,y = smt.BitVecs("x y", 32)
329+
>>> kd.prove(smt.Concat(UnConcat(x, 4)) == x)
330+
|= Concat(Concat(Concat(Extract(31, 24, x), Extract(23, 16, x)),
331+
Extract(15, 8, x)),
332+
Extract(7, 0, x)) == x
333+
>>> kd.prove(UnConcat(smt.Concat(x,y), 2)[0] == x)
334+
|= Extract(63, 32, Concat(x, y)) == x
335+
"""
336+
assert x.size() % lane_num == 0
337+
lanesize = x.size() // lane_num
338+
return [
339+
smt.Extract((i + 1) * lanesize - 1, i * lanesize, x)
340+
for i in reversed(range(lane_num))
341+
]
342+
343+
344+
def vmap(f, n):
345+
"""
346+
347+
>>> x,y = smt.BitVecs("x y", 16)
348+
>>> kd.prove(vmap(lambda a: a, 2)(x) == x)
349+
|= Concat(Extract(15, 8, x), Extract(7, 0, x)) == x
350+
>>> vmap(lambda a,b: a - b, 2)(x, y)
351+
Concat(Extract(15, 8, x) - Extract(15, 8, y),
352+
Extract(7, 0, x) - Extract(7, 0, y))
353+
"""
354+
355+
def res(*args):
356+
return smt.Concat(
357+
[f(*smallargs) for smallargs in zip(*[UnConcat(arg, n) for arg in args])]
358+
)
359+
360+
return res

0 commit comments

Comments
 (0)