использование макросов для ограничения списков

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

define <num_prob_constraints'struct_member> "CHECK_and_SET_CONSTRAINTS <lst'exp>" as computed {

    //var cur : list of uint = <lst'exp>.as_a(list of uint);
    var t : uint =  <lst'exp>.as_a(list of uint).size(); 
    print t;
    for i from 1 to 4 {
        result = append(result,"keep ",<lst'exp>,"[",i,"]==",i,"=> ",<lst'exp>,"[",i,"]==389; \n");
    };
};

и в своем коде я использую этот макрос вот так:

struct schedule{
    n : uint;
    sched_w : list of list of int;
    CHECK_and_SET_CONSTRAINTS sched_w;
};

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

*** Error: '1' is of type 'int', while expecting type 'list of int'.
                      in code generated by macro defined at line 3 in
        sports_sched_macro.e

    keep sched_w[1]==1=> sched_w[1]==389;
             expanded at line 8 in sports_sched.e
CHECK_and_SET_CONSTRAINTS sched_w;

Есть идеи о том, что здесь не так?


person user3444042    schedule 01.09.2014    source источник


Ответы (2)


Макросы - это просто подстановки кода. Их функция - просто заменить одну строку другой (вычисленной или нет) на этапе синтаксического анализа. Это означает, что макрос будет развернут там, где вы его использовали, на этапе синтаксического анализа, который предшествует этапу генерации. Фактически, список еще не существует, и вы не можете получить доступ к его размеру и элементам. В частности, ваш макрос развертывается следующим образом:

struct schedule {
    n : uint;
    sched_w : list of list of int;
    keep sched_w[1]==2=> sched_w[1]==389;
    keep sched_w[2]==2=> sched_w[2]==389;   
    ...
    ...
};

В полученном вами сообщении об ошибке указано, что вы не можете получить доступ к определенным элементам списка явно (поскольку размер списка и значения элементов еще не определены). Если вы хотите сохранить свой список с размером 4, и если значение равно 2, вы хотите заменить его на 389, вам может потребоваться использовать метод post_generate (), поскольку вы пытаетесь получить доступ к значениям, которые уже присвоены списку Предметы:

keep sched_w.size()==4;
post_generate() is also{
    for each in sched_w  {
        if (it==2) {it=389};    
    };
}; 
person yuvalg    schedule 01.09.2014

Вы уверены, что хотите ограничить двумерный список? Это выглядит немного иначе. Например. для расписания массива [4] [1]:

schedule: list of list of int;
keep schedule.size() == 4;
keep for each (sublist) in schedule {
   sublist.size() == 1;
   for each (elem) in sublist { 
      ...
   };
};
person Thorsten    schedule 02.09.2014