2014-12-10 18 views
17

Dato due elenchi di variabili, qual è il modo più compatto e canonico in ISO Prolog per determinare l'unione di entrambi? Cioè, vogliamo una definizione per la (meta-logico) predicatiUnione di due serie variabili

varset_union(VarSet1, VarSet2, Union) 

e per una lista di liste

varset_union(VarSets, Union) 

dove Union è un elenco di variabili uniche di un dato VarSet s.

Ecco uno overview of the built-ins in ISO/IEC 13211-1: 1995 compreso Cor.2: 2012.

risposta

13

Soluzione utilizzando term_variables/2:

varset_union(VarSet1, VarSet2, Union):- 
    term_variables([VarSet1|VarSet2], Union). 

varset_union(VarSets, Union):- 
    term_variables(VarSets, Union). 

Soluzione utilizzando setof/3:

varset_union(VarSet1, Varset2, Union):- 
    varset_union([VarSet1, VarSet2], Union). 

varset_union([], []). 
varset_union(VarSets, Union):- 
    setof(Var, VarSet^(member(VarSet, VarSets), member(Var, VarSet)), Union). 
+1

noti che la definizione di 'setof/3' produrrà un elenco di variabili nell'attuazione ordine dipendente - che significa ordine essenzialmente casuale - che' term_variables/2' ha un ordine ben definito . – false

+1

E in termini di efficienza la soluzione 'setof/3' è molto peggio [almeno in SWI-Prolog]. –

+1

'setof/3' usa' term_variables/2' per determinare le variabili da elaborare. E questo è solo il primo passo ... – false

2

Basato sul grande risposta di Tudor, ho messo a punto una definizione di varset_union/3 che è più   compatta da 2 caratteri:

varset_union(VarSet1, VarSet2, Union):- 
     term_variables(VarSet1+VarSet2, Union). 

;-)

+1

In molte implementazioni, questo sarà più lento (come in SWI) e/o consumerà più spazio (come in SICStus, YAP). – false

+0

Mi sono sforzato per i criteri che hai richiesto: Compatto e canonico. Union e '+' sono strettamente correlati, quindi è almeno molto naturale usare '+' qui. – mat