2010-10-31 31 views
7

Kuralların gövdesinin önceden bilinmediği SWI-prolog kullanarak bilgi tabanına dinamik olarak bir kural eklemeye çalışıyorum. EğerSWI prologunda dinamik kural onayı

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

ama sorun gerçekler zamanında karar olmasıdır (gerçekler sayısı da bilinmeyen bir devlettir basitçe olur Normalde

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

:

istenen kural şuna benzer onaylamadan önce). Ben Biz gidiyoruz

cevap

4

[(2) (1), aslında gerçekte] gibi vücut gerçekleri bir listeden oluşan bir kural savunmak için bir olasılık olup olmadığını bilmek istiyorum neden

budur newrule(X) :- w,x,y,z(X) kuralı oluşturun.
Bir kuralın gövdesi, (w, x, y ...) biçimindeki bir yapıdır. bir gövde ile başlayan farklı vücut uzunlukları için

:

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

demet operatörün olarak, virgül (''), bir, '(a, b) == (a, b).

%%%% 
%%%% 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). 

-

iki giriş var. İlk liste, create_a_rule()'da çağrılan listing()'dan kaynaklanır. 2. listeleme, son kaynak satırındaki listing() komutundan. frayser girişine yönlendiren

?- [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

Mükemmel ve çok ayrıntılı bir çözüm için çok teşekkür ederim! – Tom

+0

@ Tom: Eğer cevap "mükemmel" ise, neden kabul etmiyorsunuz? –

+0

Bu yanıtta ['assert'] (http://www.swi-prolog.org/pldoc/man?predicate=assert/1) yüklemesi, SWI-Prolog'da kullanımdan kaldırılmıştır. –

1

de Önerilen değişiklik: İlk değişken boş bir liste ise

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

Bu hükümler istisna edilmesi ihtiyacını ortadan kaldırmak: basitçe başarısız olur. Aynı zamanda, geri adım attığınız zaman bir iddiaya asla vuramayacağınız anlamına gelir. Bununla birlikte, yine de istisna maddesini YERELLEŞTİRMEK İSTEMİYORSANIZ, bu yüzden hala [] ile birleşme denemesi yapılan vakaları yakalamak için koyabilirdiniz. (Gerçi, geri çekerken vurmaz.)