2014-12-10 23 views
17

Biorąc pod uwagę dwie listy zmiennych, jaki jest najbardziej kompaktowy i kanoniczny sposób w ISO Prolog, aby określić związek obu? Oznacza to, że chcemy definicję dla (meta-logiczna) predykatówZwiązek dwóch zmiennych zbiorów

varset_union(VarSet1, VarSet2, Union) 

oraz lista list

varset_union(VarSets, Union) 

gdzie Union jest lista unikalnych zmiennych danego VarSet s.

Oto overview of the built-ins w ISO/IEC 13211-1: 1995, w tym Cor.2: 2012.

Odpowiedz

13

rozwiązanie wykorzystujące term_variables/2:

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

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

rozwiązanie wykorzystujące 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

Należy zauważyć, że definicja z 'setof/3' będzie produkować listę zmiennych w kolejności zależnej od realizacji - co oznacza w zasadzie losowej kolejności - podczas gdy' term_variables/2' ma dobrze zdefiniowaną kolejność . – false

+1

I pod względem wydajności rozwiązanie 'setof/3' jest znacznie gorsze [przynajmniej w SWI-Prolog]. –

+1

'setof/3' używa' term_variables/2' do określenia zmiennych do przetworzenia. A to dopiero pierwszy krok ... – false

2

oparciu o wielkiej odpowiedź Tudor, I opracowali definicję varset_union/3 czyli więcej   kompaktowy przez 2 znaki:

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

;-)

+1

W wielu implementacjach będzie to wolniejsze (jak w SWI) i/lub zużywa więcej miejsca (jak w SICStus, YAP). – false

+0

Starałem się o kryteria, o które prosiłeś: Kompaktowy i kanoniczny. Union i '+' są ze sobą ściśle powiązane, więc używanie "+" tutaj jest co najmniej bardzo naturalne. – mat

Powiązane problemy