Files
app-store-optimization/skills/loki-mode/benchmarks/results/2026-01-05-10-37-54/swebench-loki-patches/sympy__sympy-17630.patch

116 lines
5.3 KiB
Diff

# sympy__sympy-17630
# Loki Mode Multi-Agent Patch
# Attempts: 1
The sympy repository is not available locally. Based on the issue description and the architect's analysis, I can generate the patch for the upstream SymPy repository. The bug is well-documented: when `ZeroMatrix * ZeroMatrix` or similar operations occur in `_blockmul`, the result is a scalar `Zero` instead of `ZeroMatrix`, causing subsequent operations to fail.
```
--- a/sympy/matrices/expressions/blockmatrix.py
+++ b/sympy/matrices/expressions/blockmatrix.py
@@ -1,5 +1,6 @@
from __future__ import print_function, division
+from sympy import S
from sympy.assumptions.ask import ask, Q
from sympy.core import Basic, Add
from sympy.strategies import typed, exhaust, condition, do_one, unpack
@@ -88,6 +89,23 @@ class BlockMatrix(MatrixExpr):
def colblocksizes(self):
return [self.blocks[0, i].cols for i in range(self.blockshape[1])]
+ def _ensure_zero_matrix(self, block, rows, cols):
+ """Convert scalar Zero to ZeroMatrix with proper dimensions."""
+ from sympy.matrices.expressions.matexpr import ZeroMatrix
+ if block == S.Zero:
+ return ZeroMatrix(rows, cols)
+ return block
+
+ def _get_block_sizes(self, blocks, rowblocksizes, colblocksizes):
+ """Get row and column sizes for each block position."""
+ result = []
+ for i in range(len(rowblocksizes)):
+ row = []
+ for j in range(len(colblocksizes)):
+ row.append((rowblocksizes[i], colblocksizes[j]))
+ result.append(row)
+ return result
+
def _blockmul(self, other):
if (isinstance(other, BlockMatrix) and
self.colblocksizes == other.rowblocksizes):
@@ -95,8 +113,14 @@ class BlockMatrix(MatrixExpr):
for i in range(self.blockshape[0])
for j in range(other.blockshape[1])]
- return BlockMatrix(Matrix(self.blockshape[0], other.blockshape[1], block_mul))
- return self * other
+ result = BlockMatrix(Matrix(self.blockshape[0], other.blockshape[1], block_mul))
+ # Convert any scalar Zero entries back to ZeroMatrix with proper dimensions
+ rowsizes = self.rowblocksizes
+ colsizes = other.colblocksizes
+ new_blocks = [[self._ensure_zero_matrix(result.blocks[i, j], rowsizes[i], colsizes[j])
+ for j in range(result.blockshape[1])]
+ for i in range(result.blockshape[0])]
+ return BlockMatrix(Matrix(new_blocks))
+ return self * other
def _blockadd(self, other):
if (isinstance(other, BlockMatrix)
```
Wait, I need to reconsider this approach. The issue is that when we compute `MatMul(A, ZeroMatrix)` or `MatMul(ZeroMatrix, ZeroMatrix)`, it gets simplified to scalar `Zero` rather than `ZeroMatrix`. The fix should handle this in the `_blockmul` method where the matrix multiplication results are computed.
Let me provide a cleaner patch:
```
--- a/sympy/matrices/expressions/blockmatrix.py
+++ b/sympy/matrices/expressions/blockmatrix.py
@@ -163,6 +163,8 @@ def bc_matmul(expr):
def bc_block_plus_ident(expr):
pass
+from sympy.matrices.expressions.matexpr import ZeroMatrix
+
def _block_mul(A, B):
"""Multiply two block matrices.
Assumes that both matrices have conforming block structures.
@@ -176,6 +178,10 @@ def _block_mul(A, B):
block = Add(*[A.blocks[i, k] * B.blocks[k, j]
for k in range(A.blockshape[1])])
blocks[i*n + j] = block
+ # Convert scalar Zero back to ZeroMatrix with proper dimensions
+ from sympy import S
+ if blocks[i*n + j] == S.Zero:
+ blocks[i*n + j] = ZeroMatrix(A.rowblocksizes[i], B.colblocksizes[j])
return BlockMatrix(Matrix(m, n, blocks))
```
Actually, let me reconsider. Looking at the traceback more carefully, the issue is in the `_blockmul` method itself. The patch should be applied there. Let me provide a complete, clean patch:
--- a/sympy/matrices/expressions/blockmatrix.py
+++ b/sympy/matrices/expressions/blockmatrix.py
@@ -89,13 +89,20 @@ class BlockMatrix(MatrixExpr):
return [self.blocks[0, i].cols for i in range(self.blockshape[1])]
def _blockmul(self, other):
+ from sympy.matrices.expressions.matexpr import ZeroMatrix
+ from sympy import S
if (isinstance(other, BlockMatrix) and
self.colblocksizes == other.rowblocksizes):
- block_mul = lambda i, j: Add(*[self.blocks[i, k]*other.blocks[k, j]
- for k in range(self.blockshape[1])])
-
- return BlockMatrix(Matrix(self.blockshape[0], other.blockshape[1], block_mul))
- return self * other
+ def block_mul(i, j):
+ result = Add(*[self.blocks[i, k]*other.blocks[k, j]
+ for k in range(self.blockshape[1])])
+ # Convert scalar Zero to ZeroMatrix with proper dimensions
+ if result == S.Zero:
+ return ZeroMatrix(self.rowblocksizes[i], other.colblocksizes[j])
+ return result
+ return BlockMatrix(Matrix(self.blockshape[0], other.blockshape[1], block_mul))
+ return self * other
def _blockadd(self, other):
if (isinstance(other, BlockMatrix)