Formula solver seems to work, now the UI should be reworked

This commit is contained in:
Álvaro González 2026-03-05 18:27:07 +01:00
parent 5fabb4424c
commit e3c5d9cef9
2 changed files with 104 additions and 38 deletions

View file

@ -117,9 +117,7 @@ class FormulaEvaluator {
} catch (e, stack) {
// SPECIAL CASE: If the error message starts with signalMagicString, treat it as a signal message and return it instead of throwing an exception
// SEE signal() function in the generated d4rt code above for how this is used
print("#######################");
if (e.toString().contains(signalMagicString)) {
print("***********************");
final signalMessage = e.toString().split(signalMagicString).last.trim();
return signalMessage;
}
@ -295,6 +293,52 @@ class FormulaEvaluator {
}
}
Number formulaSolver(Formula formula,
String variableToSolve,
Map<String, dynamic> fixedInputValues, {
Number hint = 0,
Number step = 10,
Number maxDelta = 0.01,
int maxTries = 100,
}) {
if( variableToSolve == formula.output.name ){
return FormulaEvaluator().evaluate(formula, fixedInputValues);
}
if (!formula.inputVarNames().contains(variableToSolve) ){
throw ArgumentError(
'Variable "$variableToSolve" is not an input or output variable of the formula "${formula
.name}".',
);
}
final modifiedInputValues = Map<String, dynamic>.from(fixedInputValues);
var evaluator = FormulaEvaluator();
Number f(Number x) {
modifiedInputValues[variableToSolve] = x;
final result = evaluator.evaluate(formula, modifiedInputValues);
if (result is Number) {
return result;
} else {
throw FormulaEvaluationException(
'Expected formula evaluation to return a number, but got: $result ${result.runtimeType}',
);
}
}
var fixedFormulaOutput = fixedInputValues[formula.output.name];
return functionSolver(
(Number x) => f(x) - fixedFormulaOutput,
hint: hint,
step: step,
maxDelta: maxDelta,
maxTries: maxTries,
);
}
class NoSolutionException implements Exception {
final String message;

View file

@ -5,6 +5,26 @@ import 'dart:math' as Math;
void main() {
group("Formulas", (){
test("Solve x^2 formula", () {
final formula = Formula(
name: 'Test x^2',
input: [
VariableSpec(name: 'x', unit: 'scalar'),
],
output: VariableSpec(name: 'y', unit: 'scalar'),
d4rtCode: 'y = x*x;',
);
var solution = formulaSolver(formula, "x", {"y": 25}, maxDelta: 1e-10);
expect( solution, closeTo(5, 1e-10));
});
});
group('Native functions', () {
test("Solve x^2", () {
Number f(Number x) => x * x;
var root = functionSolver(f, hint: 10, step: 1);
@ -21,7 +41,8 @@ void main() {
test("Solve x^2 + 1", () {
Number f(Number x) => x * x + 1;
expect(()=> functionSolver(f, hint: 10, step: 1), throwsA(isA<NoSolutionException>()));
expect(() => functionSolver(f, hint: 10, step: 1),
throwsA(isA<NoSolutionException>()));
});
test("Solve (x-2)(x-10", () {
@ -53,5 +74,6 @@ void main() {
var root = functionSolver(f, hint: 1, step: 1);
expect(root, closeTo(Math.log(2), 0.01));
});
});
}