Генерация кода клена: Как объявить переменные автоматически? - PullRequest
1 голос
/ 28 февраля 2011

В Maple (версия 14, если это имеет значение) я определяю процедуру, которая использует глобально определенное выражение в maple, но когда я перехожу к генерации кода, она предполагает, что переменная не та, которую я ожидаю.

a:=x+y*x
p := proc (x::float, y::float); return a; end proc;
C(p)

Я ожидаю, что это функция C с выражением, вставленным в код, но вместо этого я получаю ...

double p (double x, double y)
{
  return(a);
}

1 Ответ

2 голосов
/ 01 марта 2011

Это одна из тех «дизайнерских» вещей.Даже если вам может показаться неловким в этой конкретной ситуации, такое лексическое поведение со стороны (современного) со стороны Maple чаще всего является преимуществом и является вполне осознанным.И есть несколько способов обойти это ожидание.

Самый простой обходной путь, в данном случае, может быть следующим:

restart:
a:=x+y*x:
p := proc(x::float, y::float) return a; end proc;

          p := proc(x::float, y::float) return a end proc;

CodeGeneration:-C( subs('a'=a,eval(p)) );

  double cg (double x, double y)
  {
     return(x + y * x);
  }

То, что достигнуто выше, это то, что subs('a'=a,eval(p))формирует новый экземпляр proc p, в котором a заменяется в теле proc явным значением a (т. е. чем оценивается a).Обратите внимание на вывод следующего и сравните с выводом выше при первоначальном создании p,

subs('a'=a,eval(p));

   proc(x::float, y::float) return x + y*x end proc;

Имейте в виду, что, хотя в этом очень простом обходном примере это не очевидно, данная заменапоскольку глобальные имена x и y в этой копии p фактически играют в хитрую игру с правилами определения области действия Maple.В более сложных ситуациях это может привести в бешенство.Но если то, что вы действительно хотите, это встраивание, то вы можете получить это более явным и контролируемым образом.Посмотрите на отраженный вывод p при первоначальном создании в следующем примере:

restart:
a := proc(A,B) option inline; A+B*A: end proc;
          a := proc(A, B) option inline; A + B*A end proc;

p := proc(x::float, y::float) return a(x,y); end proc;
       p := proc(x::float, y::float) return x + y*x end proc;

CodeGeneration:-C( p );

   double p (double x, double y)
   {
     return(x + y * x);
   }

Надеюсь, этих двух подходов достаточно, чтобы увидеть вас.

Давайте кратко вернемся к вашему оригиналуНапример, просто чтобы заметить что-то.Глобальные имена x и y в том виде, как они появляются в значении a, во многом не совпадают с именами двух формальных параметров первоначально созданной процедуры p.Это совершенно разные примеры того, что кажется одним и тем же именем.Рассмотрим,

restart:
a:=x+y*x:

p := proc(x::float, y::float) return a; end proc;

          p := proc(x::float, y::float) return a end proc;

p(4.0, 5.0);
                               x + y x
...