Очень основы: как создавать и управлять списками в Прологе? - PullRequest
1 голос
/ 24 января 2020

Я совсем недавно начал изучать Пролог, и хотя я до сих пор очень незнаком с ним, поэтому он кажется "странным" по сравнению с другими языками, которые я использовал ранее (C#, Java et c), это тоже немного интересно.

Что касается сейчас, я начал работать со структурами / списками. Используя классический пример, я решил создать некую базу данных в памяти.

Полный код, который у меня есть на данный момент:

addBook(title, author, year, company, books):-
append( [title, author, year, company], books ).

findBookByCompany(list, company):-
    member(company, list).

findBookByAuthor(list, author):-
    member(author, list).

findBookByYear(list, year):-
    member(year, list).

?-addBook("Book 1", "Author 1", 2012, "Company 1", books).
?-addBook("Book 2", "Author 1", 2012, "Company 1", books).
?-addBook("Book 3", "Author 2", 2014, "Company 1", books).
?-addBook("Book 4", "Author 3", 2015, "Company 2", books).
?-addBook("Book 5", "Author 4", 2016, "Company 3", books).

?-findBookByAuthor(books, "Author 1").
?-findBookByYear(books, 2011).

Теперь, это работает? Нет. Но я знаю, что я пытаюсь сделать. Я пытаюсь использовать функцию / предикат addBook(), чтобы создать 5 разных книг и сохранить их в переменной books. После этого я также пытаюсь поэкспериментировать с проверкой, есть ли в указанном списке книги, где Автор Author 1 или год 2011.

Я собираюсь предположить, что это не совсем то, что я ожидаю, все, что мне действительно нужно go, это сообщение об ошибке / предупреждение, которое я получаю: Goal (directive) failed: user:addBook(), и то же самое для двух функций / предикатов find.

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

Спасибо!

1 Ответ

1 голос
/ 24 января 2020

Самая базовая c версия вашего кода, которую я могу придумать, такова:

book("Book 1", "Author 1", 2012, "Company 1").
book("Book 2", "Author 1", 2012, "Company 1").
book("Book 3", "Author 2", 2014, "Company 1").
book("Book 4", "Author 3", 2015, "Company 2").
book("Book 5", "Author 4", 2016, "Company 3").

findBookByCompany(Company,Name) :- book(Name,_,_,Company).
findBookByAuthor(Author,Name) :- book(Name,Author,_,_).
findBookByYear(Year,Name) :- book(Name,_,Year,_).

?-findBookByAuthor("Author 1",Name),write(Name),nl,fail.

Пролог - это изложение фактов и правил, а затем проверка гипотезы.

Вы не строите список книг, вы просто излагаете факты о книгах.

Если затем вы хотите узнать, есть ли книга от определенного автора, вы создаете правило. Чтобы findBookByAuthor(Author,Name) был успешным, book(Name,Author,_,_) должен быть успешным, и вы go оттуда.

Моя вышеприведенная программа выводит следующее:

Book 1
Book 2
No.

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


Если вы хотите написать это более подробно процедурным путем, тогда вы можете сделать это:

?-
    append([], [book("Book 1", "Author 1", 2012, "Company 1")], X1s),
    append(X1s, [book("Book 2", "Author 1", 2012, "Company 1")], X2s),
    append(X2s, [book("Book 3", "Author 2", 2014, "Company 1")], X3s),
    append(X3s, [book("Book 4", "Author 3", 2015, "Company 2")], X4s),
    append(X4s, [book("Book 5", "Author 4", 2016, "Company 3")], X5s),
    member(book(Name,"Author 1",_,_),X5s),
    write(Name),
    nl,
    fail.

Это не хороший Пролог, хотя. Вам следует избегать этого.

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