Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 我可以在Prolog中共享catch调用中的变量吗?_Algorithm_Prolog - Fatal编程技术网

Algorithm 我可以在Prolog中共享catch调用中的变量吗?

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),

我正在用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总是被实例化为空列表[],我开始认为它有问题

我想问你的第一件事是。。。呼叫对吗?我的意思是,如果在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.