2014-09-01 2 views
0

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

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; 

Любые идеи о том, что здесь не так?

ответ

1

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

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};  
    }; 
}; 
0

Вы уверены, что хотите ограничить 2-мерный список? Это выглядит несколько иначе. Например. для графика шкалы [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 { 
     ... 
    }; 
};