2014-12-10 4 views
17

Учитывая два списка переменных, что является самым компактным и каноническим способом в ISO Prolog, чтобы определить объединение обоих? То есть, мы хотим, чтобы это определение для (мета-логический) предикатыОбъединение двух переменных наборов

varset_union(VarSet1, VarSet2, Union) 

и список списков

varset_union(VarSets, Union) 

где Union представляет собой список уникальных переменных данных VarSet с.

В настоящем стандарте: overview of the built-ins в ИСО/МЭК 13211-1: 1995, включая Cor.2: 2012.

ответ

13

Решение с помощью term_variables/2:

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

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

Решение с использованием 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

Обратите внимание, что определение с 'setof/3' будет производить список переменных, в зависимости от реализации порядка - что означает, по существу случайный порядок - в то время как' term_variables/2' имеет хорошо определенный порядок , – false

+1

И с точки зрения эффективности решение 'setof/3' намного хуже [по крайней мере, в SWI-Prolog]. –

+1

'setof/3' использует' term_variables/2' для определения обрабатываемых переменных. И это только первый шаг ... – false

2

Основываясь на большой ответ Тюдора, я разработал определение varset_union/3 что более   компактный по 2 символа:

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

;-)

+1

Во многих реализациях это будет медленнее (например, в SWI) и/или потребляет больше места (например, в SICStus, YAP). – false

+0

Я стремился к критериям, которые вы просили: Компактный и канонический. Союз и '+' тесно связаны, поэтому, по крайней мере, очень естественно использовать '+' здесь. – mat

Смежные вопросы