Interpretando fórmulas com F#
Quão difícil é implementar um interpretador de fórmulas matemáticas em F#? Dependendo da situação pode ser algo simples ou ser algo tão complexo que vai ser difícil de manter futuramente.
Entretanto, como em várias situações do nosso dia a dia, não é necessário reinventar a roda. Para isto podemos utilizar da biblioteca Math.NET Symbolics, que fornece suporte básico para interpretação de fórmulas algébricas.
Para demonstrar a sua utilização usaremos a versão de F# disponível no .NET 5. Depois de instalar abra o terminal e execute o comando a seguir para verificar se está tudo ok:
🐚 dotnet — version
5.0.202
Com o .NET instalado crie um arquivo chamado test.fsx com seu editor de texto favorito e adicione o código a seguir:
#!/usr/bin/env -S dotnet fsi
#r “nuget: MathNet.Symbolics, 0.24.0”
open System
open MathNet.Symbolicslet formula1 = “a+b”
let formula2 = “1/(a*b”
let formula3 = “1/(a*b)”
let a = 0.5
let b = 0.5let evaluate parsed a b formula =
let values = Map.ofList [“a”, FloatingPoint.Real a; “b”, FloatingPoint.Real b]
let result = Evaluate.evaluate values parsed
printfn “🟢 %s = %f” formula result.RealValuelet parse formula a b =
let parsed = Infix.tryParse formula
match parsed with
| Some(parsed) -> evaluate parsed a b formula
| None -> printfn “🔴 Error”parse formula1 a b
parse formula2 a b
parse formula3 a b
Vamos ver o que temos?
Na primeira parte iniciamos o nosso ambiente:
#!/usr/bin/env -S dotnet fsi
#r “nuget: MathNet.Symbolics, 0.24.0”
open System
open MathNet.Symbolics
Em seguida criamos as fórmulas que queremos interpretar e os valores dos símbolos:
let formula1 = “a+b”
let formula2 = “1/(a*b”
let formula3 = “1/(a*b)”
let a = 0.5
let b = 0.5
A partir de uma expressão (interpretada pela função parse) obtemos o valor calculado, que é mostrado na tela:
let evaluate parsed a b formula =
let values = Map.ofList [“a”, FloatingPoint.Real a; “b”, FloatingPoint.Real b]
let result = Evaluate.evaluate values parsed // interpretação
printfn “🟢 %s = %f” formula result.RealValue
A fórmula recebida em formato de string é interpretada e transformada em uma expressão que é passada para a função evaluate (mostrada acima):
let parse formula a b =
let parsed = Infix.tryParse formula
match parsed with
| Some(parsed) -> evaluate parsed a b formula
| None -> printfn “🔴 Error”
Por último interpretamos cada uma das fórmulas:
parse formula1 a b
parse formula2 a b
parse formula3 a b
Mas como executar tudo isso?!
Para executar primeiramente abra o terminal na pasta onde o arquivo se encontra.
No Windows execute com dotnet fsi test.fsx.
No Linux ou macOS mude a permissão do arquivo com chmod +x test.fsx e em seguida execute com ./test.fsx.
Teremos a seguinte saída de texto:
🐚 ./test.fsx
🟢 a+b = 1.000000
🔴 Error
🟢 1/(a*b) = 4.000000
Voilá! Temos nosso interpretador de fórmulas algébricas!
Até a próxima!