2013-03-20 34 views
1

我正在開發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),  /* 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)) 
    ). 

的事情是,內部的「設置的,條件 - 檢查「,activable/1可能會間接調用。這就是爲什麼我需要使用checked/1,以避免不必要的循環。 我猜我使用findall/3的方式還行,但由於As總是被實例化爲空列表[]我開始認爲它有什麼問題。

我想問你的第一件事是趕(...)電話。這是對的嗎?我的意思是,如果在調用activable/1期間,程序拋出一個異常,因爲任務已經被檢查,A仍然會被實例化(這樣我可以在flag(marked_activable,A)中使用它)?如果沒有,你知道任何解決方法嗎?

我想問你的第二件事是關於我的算法的正確性。我一直在研究這個問題很久,我盡我所能擁有了一個高效,強大和可靠的代碼。真正困難的是在條件檢查中,任務的關係扮演着重要的角色並創造出複雜的約束。你認爲「找到可行的任務」的方式是好的嗎?

+0

不需要的循環可能會出現,因爲我檢查任務之間的關係。他們可以是「依賴性」或「排他性」關係,在這兩種情況下,我都會檢查這些關係是否是活動/不活動。 – 2013-03-20 17:20:24

+0

而不是留下您自己的問題的意見,你應該編輯問題,並納入信息。 – 2013-03-20 17:59:38

+0

好的!感謝您的建議,從現在開始我會記住這一點。 – 2013-03-21 10:03:31

回答

0

使用內置的catch/3謂詞,傳遞信息的正確方法是通過Catcher術語。

catch(:Goal, +Catcher, :Recover) 

根據SWI-Prolog的文檔,該Goal是最裏面的目標,其中Catcherthrow/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. 
相關問題