2013-03-20 2 views
1

Я разрабатываю планировщик задач в Prolog. Прежде всего позвольте мне показать вам упрощенную версию моего кода. Это выглядит следующим образом:Могу ли я использовать переменные в вызове catch в Prolog?

handle_activable(As) :- 
    reset_flags, 
    findall(A,catch(activable(A),Exception,flag(marked_activable,A)),As), 
    activate_all(As). 

Есть две версии activable/1, но наиболее значимым из них (опять упрощены):

activable(T) :- 
    task(T),  /* T is a task */ 
    inactive(T), /* The task is currently inactive */ 
    (\+checked(T) -> 
     mark_checked(T), 
     !, 
     /* 
      Here would go the set of conditions 
      and statements to determine if task T 
      is activable or not. They may internally 
      call activable/1. 
     */ 
     asserta(flag(marked_activable,T)) 
    ; 
     /* 
      This task was already checked and the 
      result is stored in flag(marked_activable,T) 
      fact. 
     */ 
     throw(exception(already_checked,T)) 
    ). 

Дело в том, что в рамках «множество-условия- check ", activable/1 можно косвенно назвать. Вот почему мне нужно использовать checked/1, чтобы избежать нежелательных петель. Я догадался, как я использую findall/3 было нормально, но так как As всегда создается как пустой список [] Я начинаю думать, что с ним что-то не так.

Первое, что я хотел бы задать вам, это вызов catch (...). Правильно ли это? Я имею в виду, что если во время вызова activable/1 программа выдает исключение, потому что задача уже была проверена, будет ли создан экземпляр A (чтобы я мог использовать его в flag(marked_activable,A))? Если нет, знаете ли вы какое-либо обходное решение?

Вторая вещь, которую я хотел бы задать вам, касается правильности моего алгоритма. Я работаю над этим так долго, и я сделал все возможное, чтобы иметь эффективный, надежный и надежный код. Реальная сложная вещь находится в пределах проверки условий условий, где отношения задачи играют большую роль и создают сложные ограничения. Считаете ли вы, что способ «найти активируемые задачи» является хорошим?

+0

Нежелательные петли могут появиться, потому что проверить отношения между задачами. Они могут быть отношениями «зависимости» или «эксклюзивности», и в обоих случаях я проверяю, являются ли эти отношения активными/неактивными. –

+0

Вместо того, чтобы оставлять комментарии по собственному вопросу, вы должны просто отредактировать вопрос и включить информацию. –

+0

Хорошо! Спасибо за совет, я буду держать это в виду с этого момента. –

ответ

0

Использование встроенного предиката catch/3, правильный способ передачи информации осуществляется через период Catcher.

catch(:Goal, +Catcher, :Recover) 

В соответствии с SWI-Prolog дока, то Goal является внутренней целью, к которой Catcher объединяет с аргументом throw/1, все точки выбора, порожденные Goalразрежут и система откатывается к началу catch/3 времени сохраняя исключенный термин исключения. Таким образом, имея правило, как:

generate(info1). 
generate(info2). 
generate(info3). 
generate(info4). 
rule(D) :- 
    generate(D), 
    ... 
    throw(error_info(D)). 

Результат ловли это правило было бы что-то подобное:

?- catch(rule(D), Exception, write(Exception)). 
error_info(info1). 
Exception = error_info(info1). 

?- catch(rule(_), error_info(E), write(E)). 
info1. 
E = info1. 
Смежные вопросы