Я пытаюсь написать небольшой скрипт, который будет смотреть на первый член выражения и определять, является ли он положительным или отрицательным, а затем печатать +
или -
перед этим выражением соответственно; однако у меня возникли некоторые проблемы с написанием его таким образом, чтобы он надежно извлекал первый член выражения.
Я экспериментировал с part
и args
. Я склоняюсь к args
, потому что не нашел способа определить глубину parts
для произвольного выражения (т.е. я не уверен, как можно определить, следует ли использовать, например, part(expr,1)
или part(expr,1,1)
или part(expr, 1,1,1)
и т. д.).
Проблема с args
заключается в том, что, например,
declare(cos, posfun)$
args(-2*cos(x));
> [2 cos(x)]
т.е. отрицание отбрасывается, предположительно из-за шепелявого представления выражения (тот же результат мы получаем от part(-2*cos(x),1)
; более того, part(-2*cos(x),2)
отваливается от конца -- кажется, part
просто не видно -
).
Напротив,
args(-2*cos(x)+x);
> [x, -2cos(x) ]
как и ожидалось.
Независимо от того, является ли это желаемым поведением для этих функций, я надеялся найти способ обойти это, чтобы у меня была функция, которая имела бы следующее поведение:
addOp(x) > ["+", x]
addOp(-x) > ["-", x]
addOp(1+2*x+x^2) > ["+", 1+2*x+x^2]
addOp(-2+2*x+x^2) > ["-", 2+2*x+x^2] /* NB: only the first term is scaled by -1, not the entire expression */
addOp(cos(...)) > ["+", cos(...)]
addOp(-2x*cos(...)) > ["-", 2x*cos(x) ]
Я также пытался использовать функцию op
вместе с известным числом; однако внутреннее представление отрицательных чисел означает, что что-то вроде op(1-3*cos(x))
возвращает +
.
Это заставило меня некоторое время тупить, поэтому любые предложения будут очень признательны.