Prolog: perbedaan antara var, nonvar dan ground
Dalam Prolog, terutama pada aspek metaprogramming, orang sering membicarakan variabel ground dan non ground . Serta menggunakan predikat seperti var / 1 , nonvar / 1 dan ground / 1 . Tapi apa sebenarnya perbedaan di antara keduanya?
Pemahaman saya saat ini adalah sebagai berikut:
- Sebuah var benar-benar tidak berdasar (mis. X)
- Sebuah nonvar dipakai, tetapi mungkin berisi beberapa variabel lebih dalam (misalnya istilah (1,2, Y)). Ini mirip dengan bentuk normal kepala lemah dari Haskell.
- Sebuah var tanah benar-benar dipakai, semua jalan (misalnya. Istilah (1,2,3)).
Apakah ini benar?
Jawaban
Hampir.
Jika
var(X)
kemudian variabelX
menunjuk sesuatu yang tidak berdasar, sebuah "lubang".X
adalah "variabel segar". Catatan: Predikat itu harus benar-benar dinamaifresh(...)
. ApakahX
variabel sebenarnya adalah pertanyaan tentang teks program. Tapi yang ingin kita ketahui adalah apakah yang ada di antara tanda kurung adalah variabel baru (pada saat panggilan itu dibuat, karena, secara non-logis, itu bisa berubah.)nonvar(X)
hanyalah pelengkapvar(X)
, sama seperti\+ var(X)
. Apapun yang ada di antara tanda kurung menunjukkan sesuatu (jika itu adalah variabel) atau adalah sesuatu (jika itu adalah suku non-variabel, seperti dalamnonvar(foo)
) yang bukan "lubang".ground(X)
berarti bahwa apapun yang berada di antara tanda kurung menunjukkan sesuatu atau sesuatu yang tidak memiliki lubang pada strukturnya (pada dasarnya, tidak ada lubang pada daun istilah itu).
Beberapa kode tes. Saya berharap kompiler mengeluarkan lebih banyak peringatan daripada yang dilakukannya.
:- begin_tests(var_nonvar).
% Amazingly, the compiler does not warn about the code below.
test("var(duh) is always false", fail) :-
var(duh).
% Amazingly, the compiler does not warn about the code below.
test("var(X) is true if X is a fresh variable (X designates a 'hole')") :-
var(_).
% Compiler warning: " Singleton variable, Test is always true: var(X)"
test("var(X) is true if X is a fresh variable (X designates a 'hole')") :-
var(X).
% The hole designated by X is filled with f(_), which has its own hole.
% the result is nonvar (and also nonground)
test("var(X) maybe true but become false as computation progresses") :-
var(X),X=f(_),nonvar(X).
test("var(X) is false otherwise") :-
var(_).
% The hole is designated by an anonymous variable
test("a fresh variable is not ground, it designates a 'hole'", fail) :-
ground(_).
% Both hhe holes are designated by anonymous variables
test("a structure with 'holes' at the leaves is non-ground", fail) :-
ground(f(_,_)).
test("a structure with no 'holes' is ground") :-
ground(f(x,y)).
test("a structure with no 'holes' is ground, take 2") :-
X=f(x,y), ground(X).
% var/1 or ground/1 are questions about the state of computation,
% not about any problem in logic that one models. For example:
test("a structure that is non-ground can be filled as computation progresses") :-
K=f(X,Y), \+ ground(f(X,Y)), X=x, Y=y, ground(f(X,Y)).
:- end_tests(var_nonvar).