- È il predicato sopra più/3 veramente puro?
Ha un po 'strano comportamento: A volte accetta espressioni aritmetiche, e qualche volta no; e questo anche se tutti gli argomenti vengono valutati:
?- plus(3,5-3,5).
true ...
?- plus(3,2,3+2).
false.
?- plus(3,2,3+b).
ERROR: </2: Arithmetic: `b/0' is not a function
?- plus(3,2,3+Z).
ERROR: </2: Arguments are not sufficiently instantiated
avrei preferito essere preoccupato per l'inefficienza del nat/1
per casi come:
?- time((nat(X), X > 9999)).
% 50,025,002 inferences, 27.004 CPU in 27.107 seconds (100% CPU, 1852480 Lips)
X = 10000 ;
% 10,006 inferences, 0.015 CPU in 0.015 seconds (99% CPU, 650837 Lips)
X = 10001 ;
% 10,005 inferences, 0.016 CPU in 0.016 seconds (99% CPU, 631190 Lips)
X = 10002 ...
Quindi, mi sembra che la definizione è puro. Tuttavia, questo stile di programmazione rende abbastanza difficile garantire questa proprietà. Un minimo cambiamento avrà effetti disastrosi.
- In generale, come si può dimostrare che un particolare relazione ha la purezza logica?
Il modo più semplice è la costruzione. Cioè, usando solo blocchi di costruzione monotonici puri. I.e. Prolog senza alcun built-in e usando solo congiunzione e disgiunzione di obiettivi regolari. Qualsiasi programma costruito in questo modo sarà pure e monotono. Quindi, eseguire questo programma con il flag Prolog si verifica come impostato su true
o error
.
Aggiungi a questo pure built-in come (=)/2
e dif/2
.
Aggiungi a questo built-in che tenta di emulare relazioni pure e che producono errori di istanziazione quando non sono in grado di farlo. Pensa a (is)/2
e ai predicati di confronto aritmetico. Alcuni di questi sono abbastanza al limite come call/N
che potrebbe chiamare alcuni predicati impuri.
Aggiungi library(clpfd)
con flag clpfd_monotonic
impostato su true
.
Molti costrutti sono puri e puri per determinati usi, ma impuri per gli altri. Pensare if-then-else che è perfetto per il confronto aritmetica:
..., (X > Y -> ... ; ...), ...
ma che non funziona insieme con un obiettivo puro come
..., (X = Y -> ... ; ...), ... % impure
Ciò che resta sono impuri built-in che può essere utilizzato costruire predicati che si comportano in modo puro; ma la cui definizione in quanto tale non è più pura.
Ad esempio, prendere in considerazione tagli veramente verdi. Questi sono estremamente rari e ancora più rari qui su SO. Vedi this e that.
Un altro modello comune per fornire un rapporto puro sono condizionali come:
..., (var(V) -> something with var ; the equivalent with nonvar), ...
e per evitare i casi che non sono coperti in modo pulito, gli errori possono essere gettati.
domanda coraggiosa -> +1! – mat
La [differenza tra i tagli rosso e verde] (http://stackoverflow.com/a/26483422/801553) è in qualche modo correlata a questo. –
I tagli verdi non modificano l'uscita del programma.Potrebbero mancare e le soluzioni sarebbero le stesse. Sto parlando di programmi che usano tagli rossi (come quelli nella domanda). –