Prolog: perbedaan antara var, nonvar dan ground

Aug 18 2020

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

DavidTonhofer Aug 18 2020 at 01:22

Hampir.

  • Jika var(X)kemudian variabel Xmenunjuk sesuatu yang tidak berdasar, sebuah "lubang". Xadalah "variabel segar". Catatan: Predikat itu harus benar-benar dinamai fresh(...). Apakah Xvariabel 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 pelengkap var(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 dalam nonvar(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).