100 # AdaptiveSimpson(_f, var_IsVariable, a_IsRationalOrNumber, b_IsRationalOrNumber, tol_IsRationalOrNumber) <-- [
    Local(c, fa, fb, fc, h, q, q1, q2, stp);

    c := (a + b) / 2;

    fa := N(`WithValue(@var, a, f));
    fc := N(`WithValue(@var, c, f));
    fb := N(`WithValue(@var, b, f));

    h := (b - a);
    q := (b - a) / 6 * (fa + 4 * fc + fb);

    stp(f, var, a, b, c, fa, fb, fc, q0, tol) := [
        Local(d, e, fd, fe, q, q1, q2);

        d := (a + c) / 2;
        e := (c + b) / 2;

        fd := N(`WithValue(@var, d, f));
        fe := N(`WithValue(@var, e, f));

        q1 := (c - a) / 6 * (fa + 4 * fd + fc);
        q2 := (b - c) / 6 * (fc + 4 * fe + fb);

        q := N(q1 + q2);

        If (Abs(q - q0) > tol, [
            q1 := stp (f, var, a, c, d, fa, fc, fd, q1, tol);
            q2 := stp (f, var, c, b, e, fc, fb, fe, q2, tol);
            q := N(q1 + q2);
        ]);

        q;
    ];

    stp(f, var, a, b, c, fa, fb, fc, q, tol);
];


100 # (NIntegrate(var_IsVariable, a_IsRationalOrNumber, b_IsRationalOrNumber)(_f)) <-- [
    AdaptiveSimpson(f, var, a, b, 1e-8);
];
