2014-12-29 7 views
14

Qual è il modo più compatto e canonico in ISO Prolog per verificare un elenco di variabili distinte? Chiamiamo questo predicato meta-logico is_varset/1.Verificare che il termine sia un elenco di variabili distinte

Quindi dovrebbe riuscire se il suo argomento è un elenco di variabili che sono tutte diverse. Si noti che una lista contiene sempre un [] alla sua fine. Se una variabile è alla fine, la chiamiamo lista parziale (che non è quindi una lista). E se un termine non variabile si verifica come un suffisso che non è né [] né una variabile, allora questo è né un elenco parziale né un elenco.

Un caso speciale notevole di un termine non è né un elenco parziale né un elenco sono elenchi infiniti. Contengono almeno due suffissi identici, in realtà essi posseggono infinitamente tali suffissi. Gli elenchi infiniti non rientrano nell'ambito dello standard — tutti i tentativi di crearli risultano in unificazione STO il cui risultato non è definito. Tuttavia, alcuni sistemi li supportano, quindi idealmente per quelle liste infinite, is_varset/1 dovrebbe fallire finitamente.

?- is_varset([A|nonlist]). 
false. 

?- is_varset([A,B]), is_varset([B,A]). 
true. 

?- is_varset([A,B,A]). 
false. 

?- is_varset([A,f(B)]). 
false. 

?- is_varset([A|_]). 
false. 

?- L = [_|L], is_varset(L). % may loop, should rather terminate 
false. 

Ecco un overview of the built-ins nella norma ISO/IEC 13.211-1: 1995 compresi Cor.2: 2012.

risposta

8

questa semplice definizione di SWI-Prolog sembra realizzare i requisiti

is_varset(Vs) :- /*is_list(Vs),*/ term_variables(Vs, T), T == Vs. 
+2

sembra piacevole! Potresti giustificare il motivo per cui non metti un '=' al posto di '=='? – false

+2

questo test case '? - is_varset ([A, f (B)]).' Risponde 'B = f (B) .' quando si utilizza (=)/2. Certo, ho usato (==)/2 in primo luogo basandomi sull'intuizione, e testato di nuovo dopo il tuo commento ... – CapelliC

+2

E se si usa 'unify_with_occurs_check' al posto di' == '? – false