Pertanyaan hasil unik dari prolog


Apakah ada cara mudah untuk membuat kueri di prolog hanya mengembalikan setiap hasil satu kali?

misalnya saya mencoba sesuatu seperti:

deadly(Xn) :- scary(X), Xn is X - 1, Xp is X + 1, not(safe(Xn)), safe(Xp).
deadly(Xp) :- scary(X), Xn is X - 1, Xp is X + 1, not(safe(Xp)), safe(Xn).

deadly(X).

dan mendapatkan

X = 5

X = 5

X = 5

X = 5

....

Tidak berguna untukku.


5
2018-04-07 06:35


asal


Jawaban:


Satu hal yang dapat Anda lakukan adalah menerapkannya setof/3 ke predikat yang menghasilkan solusi. Tapi perhatikan itu setof/3 diimplementasikan dengan menerapkan sort/2 untuk hasil yang dikirimkan oleh bagof/3 (setidaknya ini adalah kasus di SWI-Prolog). Jadi, jika generator solusi Anda berlangsung selamanya, lalu setof/3 tidak akan pernah diterapkan ...

Jadi saya akan mengatakan bahwa cobalah untuk memprogram agar duplikat tidak dihasilkan, yaitu dengan menggunakan cut (!) Di mana itu masuk akal.


4
2018-04-07 12:43



Jika saya ingat benar ada solusi predikat (atau serupa, sudah lama sejak saya memprogram Prolog) yang mengumpulkan solusi unik dalam daftar.

Edit:  setof/3 adalah yang aku pikirkan. Terima kasih, Kaarel.


3
2018-04-07 08:34



Pendekatan lain adalah memafalkan solusi.

:- dynamic seen/1.

% Call this always before calling deadly_wrapper/1
clear_seen :-
    retractall(seen(_)).

% This wrapper calls deadly/1 but remembers
% the solution using assert/1, and fails
% if the solution has been "seen" before.
deadly_wrapper(X) :-
    deadly(X),
    (
        seen(X)
    ->  
        fail
    ;
        assert(seen(X))
    ).  


% This is for testing.
deadly(1).
deadly(1).
deadly(1).
deadly(5).
deadly(1).
deadly(1).

Dalam hal Prolog Anda mendukung tabling, maka itu menjadi lebih sederhana. File contoh:

:- table deadly/1.

deadly(1).
deadly(1).
deadly(5).
deadly(1).
deadly(5).

Eksekusi contoh dengan XSB:

$ xsb
[xsb_configuration loaded]
[sysinitrc loaded]

XSB Version 3.2 (Kopi Lewak) of March 15, 2009
[x86_64-unknown-linux-gnu; mode: optimal; engine: slg-wam;
 scheduling: local; word size: 64]

| ?- [deadly_tab].
[Compiling ./deadly_tab]
[deadly_tab compiled, cpu time used: 0.0100 seconds]
[deadly_tab loaded]

yes
| ?- deadly(X).

X = 5;

X = 1;

no
| ?- 

3
2018-04-07 13:22



Sulit untuk mengatakan tanpa kode Anda, tetapi Anda mungkin mencari operator yang dipotong (!). Jika Anda ingin memposting definisi dari foo, Saya (atau orang lain yang mengikuti) mungkin dapat memberikan jawaban rinci / spesifik.


1
2018-04-07 06:39