Разработка решателя символьных уравнений - PullRequest
2 голосов
/ 01 декабря 2011

Для класса, который я был назначен проекту, чтобы решить основную уравнение. Для этого необходимо решить линейные уравнения. Например. некоторые уравнения, которые я должен быть в состоянии решить:

  • a * x + b = c
  • a x + b = c x + d
  • 16 * х - 9 * х = а
  • х / 16 - х / 9 = а
  • 8 * (х + 3) - 5 * (х + 4) = 12
  • x ^ 2 + 2 * x + 1 = 0
  • (x + 1) * (x - 1) = 0
  • (х + 1) (х - 1) = 2 (х-1)
  • x - 2 * sqrt (x) + 1 = 0
  • log 3 * x - log 6 = 1
  • log 3 * x - log 6 * x ^ 2 = a
  • 2 ^ (x-1) * a = 2 ^ (3 * x + 1)

Я посмотрел и нашел только несколько полезных предложений. Я пытался понять эту реализацию , но не смог понять, куда я положил арифметические правила. Я пытался прочитать исходный код Sympy, но я не знаю, где искать то, что я ищу. Я думал об определении определенных правил в текстовых файлах. Например, u - v + v = u и попытался посмотреть, как применить это правило к уравнениям.

У кого-нибудь из вас есть идея, как я мог бы спроектировать это?

Ответы [ 2 ]

1 голос
/ 01 декабря 2011

Во-первых, вы должны подумать о том, как объявить уравнение (или полиномы) для этой цели.Например, вы можете определить

data Polynomial = Polynomial [Polynomial]
   | Sum Polynomial Polynomial
   | Ln Polynomial
   | Log10 Polynomial Polynomial
   | Var String -- a named Variable
   | ...

. Для простоты работы с полиномами вы можете создать экземпляры для вашего типа данных Polynomial для Eq, Ord, Num и т. Д., Чтобы вы могли работать с полиномом так же, как счисла.

instance Num Polynomial where
    a + b = ...

Для создания этих функций вы можете легко использовать Pattern Matching:

(Sum a b) + (Sum c d) = Sum (Sum a b) (Sum c d)

Для уравнения вы можете просто использовать кортежи и создать для него новый тип:

type Equation = (Polynomial, Polynomial)

Для решения этой проблемы можно использовать такую ​​функцию:

solve :: Equation -> String -> Polynomial

... где String - это имя переменной.

Решить, чем нужноделать настоящую работу.Опять же, для этого Pattern Matching можно было бы использовать для первых шагов:

solve ((Sum (Var a) b, e) x -- solves polynomials of type a + b = c + d
    | a == x = Sum e (negate b)
    | ...

Конечно, это очень просто, и вы можете сделать это намного умнее, сократив число возможных случаев, используя нормализацию, котораяНапример, объединяет «a + a + a» в «3 * a».

1 голос
/ 01 декабря 2011

Вы можете либо написать собственный синтаксический анализатор / интерпретатор математических выражений, либо использовать уже существующий. Jep является хорошим примером синтаксического анализатора выражений с открытым исходным кодом.

В противном случае, если вы хотите знать, что компиляторы и синтаксические анализаторы делают под капотом, вы можете написать свой собственный анализатор выраженийиспользование jFlex и CUP

Кроме того, здесь является отличным учебником по antlr , который может помочь вам начать работу.

...