from __future__ import annotations
import numpy as np

def newton_solve(beta_fn, jac_fn, x0, tol=1e-12, max_iter=50):
    x = np.asarray(x0, dtype=float).copy()
    for k in range(max_iter):
        b = np.asarray(beta_fn(x), dtype=float)
        if np.linalg.norm(b, ord=2) <= tol:
            return True, x, b, k
        J = np.asarray(jac_fn(x), dtype=float)
        try:
            dx = np.linalg.solve(J, -b)
        except np.linalg.LinAlgError:
            return False, x, b, k
        # basic damping if step too large
        step = 1.0
        if np.linalg.norm(dx) > 1.0:
            step = 1.0 / np.linalg.norm(dx)
        x = x + step * dx
    b = np.asarray(beta_fn(x), dtype=float)
    return False, x, b, max_iter
