Как создать новый список прологов - PullRequest
2 голосов
/ 10 апреля 2011

Я хочу создать новый список, указав формат,

, например, у меня есть следующий список:

[ ['Test1',['US','France']],  ['Test2',['German','China','UK']]  ]

Теперь я хочу получить следующий результат:

[['Test1','US'],['Test1','France'], ['Test2','German'], ['Test2','China']], ['Test2','UK']]

Спасибо

:)

Ответы [ 3 ]

2 голосов
/ 25 июня 2015

Прямо и просто с !

<i>to_pairs([])         --> [].
to_pairs([X-Ys|XYs]) --> to_pairs_with_key(Ys, X), to_pairs(XYs).

to_pairs_with_key([]    , _) --> [].
to_pairs_with_key([V|Vs], K) --> [K-V], to_pairs_with_key(Vs, K).</i>

Пример запроса:

?- <i>phrase(to_pairs([test1-[usa,france],test2-[germany,china,uk]]), KVs).</i>
KVs = [test1-usa,test1-france,test2-germany,test2-china,test2-uk].

Обратите внимание, что мы представляем пары как (-)/2 соединения, что является широко распространенной "наилучшей практикой". Переключение на это конкретное представление имеет много преимуществ:

  • Взаимодействие со многими другими предикатами библиотеки Prolog
  • Лучшая читаемость (более сжатые термины, см. Пример ниже)
  • Повышенная эффективность

Чтобы работать с представлением, которое вы использовали в вопросах, просто добавьте две maplist/3 цели:

?- <i><a href="http://www.swi-prolog.org/pldoc/doc_for?object=use_module/1" rel="nofollow noreferrer">use_module</a>(<a href="https://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl" rel="nofollow noreferrer">library(lambda)</a>).</i>
true.

?- <i>Xss0 = [[test1,[usa,france]],
           [test2,[germany,china,uk]]],
   <a href="https://www.complang.tuwien.ac.at/ulrich/iso-prolog/prologue#maplist" rel="nofollow noreferrer">maplist</a>(\[K,Vs]^(K-Vs)^true,Xss0,Xss1),
   <a href="http://www.swi-prolog.org/pldoc/doc_for?object=phrase/2" rel="nofollow noreferrer">phrase</a>(to_pairs(Xss1),Ys0),
   maplist(\ (K-V)^[K,V]^true,Ys0,Ys1).</i>
Xss0 = [[test1,[usa,france]],[test2,[germany,china,uk]]],
Xss1 = [ test1-[usa,france] , test2-[germany,china,uk] ],
Ys0  = [ test1-usa , test1-france , test2-germany , test2-china , test2-uk ],
Ys1  = [[test1,usa],[test1,france],[test2,germany],[test2,china],[test2,uk]].
0 голосов
/ 10 апреля 2011

нерекурсивный вариант:

heads( List, NewList ) :-
    findall( [Name1, Name2],
        (
        member( [Name1, Y], List),
        member( Name2, Y)
        ),
        NewList).

Итак, мы имеем это:

?- heads([['Test1',['US','France']],['Test2',['German','China']]], X).
X = [['Test1', 'US'], ['Test1', 'France'], ['Test2', 'German'], ['Test2', 'China']].

Или мы можем создать некоторый рекурсивный предикат (он доступен только для списков с двумя названиями стран (например, ['US', 'France'])):

pooq( [], [] ).
pooq( [[Name1, [Govno, Blevota]] | Tail], List ) :-
    append( [[Name1, Govno],[Name1,Blevota]], ListNew, List ),
    pooq( Tail, ListNew ).

И что-то в этом роде:

?- pooq([['Test1',['US','France']],['Test2',['German','China']]], X).
X = [['Test1', 'US'], ['Test1', 'France'], ['Test2', 'German'], ['Test2', 'China']].

Наслаждайтесь

0 голосов
/ 10 апреля 2011

Пролог для меня тихий, но я думаю, вы должны сделать что-то вроде:

First([Key,[Head, Tail]], Res):- 

Res будет вашим окончательным списком.Если res пусто, то вы должны создать Res = [ Key, Head ] и вызвать First с [Key, [Tail], Res]

Вы видите идею?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...