Algorithm 我可以在Prolog中共享catch调用中的变量吗?
我正在用Prolog开发一个任务调度器。首先,让我向您展示我的代码的简化版本。事情是这样的:Algorithm 我可以在Prolog中共享catch调用中的变量吗?,algorithm,prolog,Algorithm,Prolog,我正在用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),
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总是被实例化为空列表[],我开始认为它有问题
我想问你的第一件事是。。。呼叫对吗?我的意思是,如果在activable/1调用过程中,程序抛出一个异常,因为任务已经被检查过了,A还会被实例化,以便我可以在Flagmared_activable中使用它吗?如果没有,你知道有什么解决办法吗
我想问你的第二件事是关于我的算法的正确性。我已经在这方面工作了很长时间,我尽了最大的努力来获得一个高效、健壮和可靠的代码。真正困难的事情是在条件集检查中,任务的关系扮演着重要角色,并创建复杂的约束。您认为查找可激活任务的方法是一种好方法吗?使用内置的catch/3谓词,传递信息的正确方法是通过Catcher术语
根据SWI Prolog doc,目标是Catcher与throw/1参数相结合的最内部目标,目标生成的所有选择点都被切割,系统返回到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.
可能会出现不需要的循环,因为我检查了任务之间的关系。它们可以是依赖关系或排他性关系,在这两种情况下,我都会检查这些关系是否可激活。与其对自己的问题留下评论,不如编辑问题并合并信息。好的!谢谢你的建议,从现在起我会记住的。
?- catch(rule(D), Exception, write(Exception)).
error_info(info1).
Exception = error_info(info1).
?- catch(rule(_), error_info(E), write(E)).
info1.
E = info1.