Пролог - Получение элемента из списка списков - PullRequest
3 голосов
/ 27 октября 2011

У меня возникают проблемы с выяснением того, как получить доступ к одному символу из списка строк, не используя рекурсию, а вместо этого вернувшись назад.

Например, у меня есть этот список строк, и я хочу иметь возможность вернуть один символ из одной из этих строк ('.' 'O', '*'). Программа, над которой я работаю, обрабатывает ее как строки и столбцы. Это факт в моей базе данных, который выглядит так:

matrix(["...o....",
        ".******.",
        "...o....",
        ".*...*..",
        "..o..*..",
        ".....*..",
        ".o...*..",
        "....o..o"].

У меня есть предикат:

get(Row,Col,TheChar) :- 

, который принимает номер строки и столбца (с индексом, начинающимся с 1) и возвращает запись (TheEntry) в этой конкретной строке и столбце.

У меня такое чувство, что моя голова предиката может быть построена неправильно, но я действительно больше сосредоточен на том, как проходить каждую строку в списке символ за символом без рекурсии и возвращать ее.

Я новичок в прологе, и у меня возникли серьезные трудности с этим.

Любая помощь будет принята с благодарностью!

Спасибо!

Ответы [ 2 ]

3 голосов
/ 27 октября 2011

Реализация get / 3 может выглядеть так:

get(Row,Col,TheChar) :-    
   matrix(M),
   nth(Row,M,RowList),
   nth(Col,RowList,TheChar).

Обратите внимание, что TheChar объединен с кодом символа, например

| ?- get(1,4,X).
X = 111

Если вы хотите, чтобы увидеть символнапример, вы можете использовать коды атомов, например,

| ?- get(4,2,X), atom_codes(CharAtom,[X]).
X = 42
CharAtom = *

Надеюсь, это поможет.

1 голос
/ 27 октября 2011

используя ваше матричное представление, вы можете сделать что-то вроде этого:

ячейка (X, Y, ячейка): - матрица (ряды), Matrix = .. [matrix | Rows], arg (X, Matrix, Cols), Row = .. [row | Cols], Arg (Y, Ряд, сотовый) .

Использование =.. для создания терминов на лету может быть намеком на то, что ваше матричное представление не является лучшим. Вы можете рассмотреть различные представления для вашей матрицы.

Предполагая "стандартную" матрицу со строками фиксированной длины, вы можете представить матрицу

A B C D
E F G H
I J K L

несколькими способами:

  • Одна строка, если значения ячеек могут быть представлены как один символ, и ваш пролог поддерживает реальные строки (а не строку как список в виде символов-атомов):

    "ABCDEFGHIJKL"
    

    Поиск простой и относительный к нулю (например, первая строка и первый столбец имеют номера 0):

    ( RowLength * RowOffset ) + ColOffset
    

    дает вам индекс для соответствующего символа в атоме. Получение состоит из простой операции с подстрокой. Это имеет преимущества скорости и простоты.

  • Составной термин - это другой вариант:

    matrix( rows( row('A','B','C','D') ,
                  row('E','F','G','H') ,
                  row('I','J','K','L')
                )
          ).
    

    Поиск по-прежнему прост:

    ячейка (X, Y, матрица, значение): - arg (X, Matrix, Row), Arg (Y, Матрица, сотовый) .

  • Третьим вариантом может быть использование базы данных для более непосредственного представления вашей матрицы с использованием предикатов базы данных asserta, assertz, retract, retractall, recorda, recordz, recorded, erase. Вы можете построить структуру фактов, например, в базе данных, например:

    matrix( Matrix_Name ).
    
    matrix_cell( Matrix_Name , RowNumber , ColumnNumber , Value ).
    

    Это имеет то преимущество, что допускает как разреженные (пустые ячейки отображать не нужно), так и зубчатые (строки могут различаться по длине) представления.

  • Другим вариантом (в крайнем случае, вы могли бы сказать) было бы перейти на процедурный язык, если ваш пролог позволяет это, и представить матрицу более ... подобным матрице образом. Я должен был сделать это один раз: мы столкнулись с огромными проблемами производительности как с памятью, так и с процессором, когда модель данных достигла определенного размера. Наше решение состояло в том, чтобы представить необходимое отношение в виде огромного массива битов, что было тривиально сделать в C (и не так много в Прологе).

Я уверен, что вы можете придумать и другие способы представления матриц.

TMTOWTDI (Тим-Тоади или «Существует больше, чем один способ сделать это»), как говорят в сообществе Perl.

...