2016-11-17 54 views
1

我嘗試使用host_ip爲主機分配IP地址。但我希望所定義的任何IP地址都應該滿足一些先決條件。首先,地址八位組不應該超過有效範圍,其次我只需要來自A類網絡10.0.0.0/8的地址。只有前提條件爲真時,如何定義規則?

我試圖用assertz但預計它不工作:

byte(X) :- integer(X), X >= 0, X =< 255. 
ip(A, B, C, D) :- byte(A), byte(B), byte(C), byte(D). 

valid_ip(A, B, C, D) :- 
    ip(A, B, C, D), 
    A = 10. 

add_host(Name, A, B, C, D) :- 
    valid_ip(A, B, C, D), 
    assertz(host_ip(Name, A, B, C, D)). 

add_host(host1, 10, 0, 0, 1). 
add_host(host2, 11, 0, 0, 1). 

規則valid_ip按預期工作:

?- valid_ip(1,2,3,4). 
false. 

?- valid_ip(10,2,3,4). 
true. 

?- valid_ip(1000,2,3,4). 
false. 

但我無法查詢的host1 IP地址。

?- host_ip(host1, X). 
ERROR: toplevel: Undefined procedure: host_ip/2 (DWIM could not correct goal) 

我的assertz用法有什麼問題?

回答

2

兩個獨立的問題:

事實與指令

你的計劃目前只包含事實的形式add_host/5

可以查詢這些事實有:

 
?- add_host(H, A, B, C, D). 
H = host1, 
A = 10, 
B = C, C = 0, 
D = 1 ; 
H = host2, 
A = 11, 
B = C, C = 0, 
D = 1. 

什麼你意思是加載文件後運行目標add_host/5,你可以用initialization/1指令做到這一點,例如:

 
:- initialization add_host(host1, 10, 0, 0, 1). 
:- initialization add_host(host2, 11, 0, 0, 1). 

請注意,加載此文件時,您將收到類似如下的警告:

 
Initialization goal failed 

您可以在目標周圍使用ignore/1來忽略失敗。

正確的元數

不過,即使你解決這個問題,並加載該文件,您可以:

 
?- host_ip(H, IP). 
ERROR: Undefined procedure: host_ip/2 
ERROR:  However, there are definitions for: 
ERROR:   host_ip/5 

在這種情況下,該錯誤信息會告訴你什麼是錯的:你主張的事實形式host_ip/5,它們的存在預期:

 
?- host_ip(H, A, B, C, D). 
H = host1, 
A = 10, 
B = C, C = 0, 
D = 1. 

爲了保持數字加在一起,可以考慮使用例如assertz(host_ip(Host,ip(A,B,C,D)),聲稱FAC ts形式host_ip/2,其中第二個參數表示  IP使用合適的化合物 術語

2

該行:assertz(host_ip(Name, A, B, C, D)).在Prolog數據庫中添加了條目host_ip(Name,A,B,C,D)。這個定義是一個謂詞host_ip,帶有五個參數,但當您查詢host_ip(host1, X).時,您需要一個具有兩個參數的謂詞host_ip。

你可以簡單地串聯的A,B,C,d的一個原子,如:

add_host(Name, A, B, C, D) :- 
    valid_ip(A, B, C, D), 
    atom_concat(A,B,X), 
    atom_concat(X,C,Y), 
    atom_concat(Y,D,Z), 
    assertz(host_ip(Name, Z)).