def back_substitution(R):
"R là ma trận bậc thang của ma trận bổ sung của hệ phương trình Ax = b"
m, n = len(R), len(R[0]) # kích thước ma trận R
# vector nghiệm (danh sách theo thứ tự ẩn)
sol = [None for _ in range(n - 1)]
# Tìm dòng dưới cùng khác không
row = m - 1
while row >= 0 and all(is_zero(R[row][j]) for j in range(n)):
row -= 1
if row >= 0 and [not is_zero(R[row][j]) for j in range(n)].index(True) == n - 1:
return None # vô nghiệm
last_pcol = n - 1
while row >= 0:
pcol = [not is_zero(R[row][j]) for j in range(n)].index(True)
for i in range(pcol, last_pcol): # các ẩn tự do
sol[i] = sympy.symbols(f"x{i + 1}")
sol[pcol] = (R[row][n - 1] - sum(R[row][j]*sol[j] for j in range(pcol + 1, n - 1)))/R[row][pcol]
last_pcol = pcol
row -= 1
# Bổ sung các ẩn tự do từ 0 đến last_pcol - 1
for i in range(0, last_pcol):
sol[i] = sympy.symbols(f"x{i + 1}")
return sol