2010-10-31 16 views
7

में गतिशील नियम सम्मिलन मैं एसडब्ल्यूआई-प्रोलॉग का उपयोग करके ज्ञान आधार पर गतिशील रूप से एक नियम जोड़ने की कोशिश कर रहा हूं जहां नियम का शरीर पहले से अज्ञात है।एसडब्ल्यूआई-प्रोलॉग

rule(a) :- fact(1), fact(2). 

आम तौर पर आप केवल राज्य

assert((rule(a):-fact(1),fact(2))). 

लेकिन समस्या यह है कि तथ्यों रनटाइम पर निर्णय लिया जाता है है (तथ्यों की संख्या भी अज्ञात है जाएगा:

वांछित नियम कुछ इस तरह दिखता दावा से पहले)।

इसलिए मैं जानना चाहता हूँ कि क्या वहाँ [(1), इस तथ्य (2) तथ्य]

उत्तर

4

हम करने जा रहे हैं जैसे एक नियम है जहां शरीर तथ्यों की एक सूची के होते हैं का दावा करने की संभावना है चाहते हैं नियम newrule(X) :- w,x,y,z(X) बनाएं।
नियम का शरीर एक ट्यूपल है, (डब्ल्यू, एक्स, वाई ...) में एक निर्माण है।

शरीर के विभिन्न लंबाई के लिए, कोई शरीर के साथ शुरू:

assert(goal). 
assert(goal:-cond). 
assert(goal:-(cond1,cond2)). 

टपल ऑपरेटर ', में के रूप में अल्पविराम (`,)' है, '(ए, बी) == (क, बी)

%%%% 
%%%% Name: runtime.pl -- Runtime rule insertion. 
%%%% 
create_a_rule :- 
    Cond=[w,x,y,z(X)], 
    Head=newrule(X), 
    list_to_tuple(Cond,Body), 
    dynamic(Head), 
    assert(Head :- Body), 
    listing(Head). 

/* 
This is a [l,i,s,t], and this is a (t,u,p,l,e). 
Convertng list to tuple: 
[] -> undefined 
[x] -> (x) == x 
[x,y] -> (x,y). 
[x,y,z..whatever] = (x,y,z..whatever) 
*/ 

list_to_tuple([],_) :- 
    ValidDomain='[x|xs]', 
    Culprit='[]', 
    Formal=domain_error(ValidDomain, Culprit), 
    Context=context('list_to_tuple','Cannot create empty tuple!'), 
    throw(error(Formal,Context)). 

list_to_tuple([X],X). 

list_to_tuple([H|T],(H,Rest_Tuple)) :- 
    list_to_tuple(T,Rest_Tuple). 

:- create_a_rule. 
:- listing(newrule). 

-

दो सूचियां मौजूद हैं। listing() से पहली लिस्टिंग परिणाम create_a_rule() में बुलाया जा रहा है। दूसरी लिस्टिंग पिछले स्रोत रेखा पर listing() कमांड से है। FRAYSER की प्रविष्टि में

?- [runtime]. 
:- dynamic newrule/1. 

newrule(A) :- 
    w, 
    x, 
    y, 
    z(A). 

:- dynamic newrule/1. 

newrule(A) :- 
    w, 
    x, 
    y, 
    z(A). 

% runtime compiled 0.01 sec, 1,448 bytes 
true. 
+2

सही और बहुत विस्तृत समाधान के लिए आपको बहुत बहुत धन्यवाद! – Tom

+0

@ टॉम: अगर उत्तर "सही" है, तो आप * इसे स्वीकार क्यों नहीं करते? –

+0

['assert'] (http://www.swi-prolog.org/pldoc/man?predicate=assert/1) इस उत्तर में भविष्यवाणी एसडब्ल्यूआई-प्रोलॉग में बहिष्कृत है। –

1

सुझाई परिवर्तन:

list_to_tuple([X],X). 

list_to_tuple([A,B],(A,B)). 

list_to_tuple([A,B|T],(A,B,Rest_Tuple)) :- 
    list_to_tuple(T,Rest_Tuple). 

इन धाराओं एक अपवाद के लिए की जरूरत को समाप्त करता है, तो पहले चर एक खाली सूची है: यह केवल असफल हो जायेगी। इसका मतलब यह भी है कि बैकट्रैकिंग के दौरान आप कभी भी एक जोर नहीं देंगे।

हालांकि, आप फिर भी अपवाद खंड चाहते हैं, ताकि आप इसे अभी भी उन मामलों को पकड़ सकें जहां [] के साथ एकीकरण का प्रयास किया गया था। (हालांकि बैकट्रैकिंग के दौरान यह इसे नहीं मारा जाएगा।)