Во-первых, я новичок в Прологе, поэтому, пожалуйста, будьте поосторожнее... Кроме того, я использую SWI-Prolog, поэтому я хочу использовать правильный синтаксис для SWI.
В данном случае я хочу определить приемных родителей (в частности, мачеху и отчима). Мой текущий синтаксис таков:
isStepFather(X, Y):-
dif (X, Y),
isMale(X),
not(isParent(X, Y)),
isMother(Z, Y), isHusband(X, Z).
Во-первых, я знаю, что иногда «не» — это «\=" или какая-то другая комбинация косых черт, так есть ли лучшая версия моего утверждения «не»? Кроме того, последняя строка должна выглядеть так: «X — отчим Y, если Z — мать Y, а X — муж Z».
Я хочу указать два Z-утверждения как одну идею/условие, поэтому помещаю их в одну строку, но имеет ли это значение? Или есть лучший способ объединить два условия, которые связаны друг с другом, но не обязательно с другими условиями?
Наконец, было бы лучше/элегантнее использовать
isWife(Z, X)
вместо
isHusband(X, Z)
чтобы Z стоял перед обоими утверждениями?
Пожалуйста, дайте мне знать ваш отзыв!
Я понимаю, что это легко происходит в более сложном коде, но мне хотелось подумать об этом абстрактно. Например, было бы легко сказать is_father(Отец, Сын):- dif (Отец, Сын), is_male(Отец), is_male(Сын). Но если абстрактно выразить это, например, X, Y, Z, то это заставляет меня задуматься: «Что именно делает любого данного человека отцом любого данного другого человека?» Например, «Сын» на самом деле может быть дочерью.
На ум приходят 2 разумных способа:
stepfather_child(SF, C) :-
mother_child(M, C),
husband_wife(SF, M),
\+ father_child(SF, C).
... и:
stepfather_child_alt(SF, C) :-
dif (F, SF),
mother_father_child(M, F, C),
husband_wife(SF, M).
Некоторые примечания по программированию:
\+
безопасно только тогда, когда переменные заземлены, поэтому переместите его после предложений, которые сделают переменные заземленнымиdif
до того, как их можно будет вызывать бессмысленно — часто из-за возвратаparent
или person
, а затем нужен какой-то другой способ узнать что-то столь же фундаментальное, как мужчина или женщина, когда, например, husband_wife
или mother_father_child
делает это очевидным по их расположению - можно сделать это более конкретным, например. mother_father_daughter
и mother_father_son
like_this
, а не likeThis
, чтобы выделялись переменные, написанные с заглавной буквы.(1) Идея isMale/isFemale заключалась в том, чтобы снова защитить результаты поиска, возвращающие результаты неправильного пола, точно так же, как функция dif () защищает от того, чтобы человек был их собственным родителем/ребенком/братом. (2) Я планирую использовать Пролог в качестве логической машины в будущих приложениях (среди прочих я родом из C++), поэтому такие имена, как mother_father_son(M, F, S), сбивают с толку чтение, когда я хочу проверить, является ли женщина матерью. любых детей. Отсюда мой синтаксис с isMother. Qt и C# часто используют этот синтаксис, плюс мне легче читать как isMother(sandra, Child) -> true = Sandra — мать некоторого ребенка.
Такие вещи являются отношениями, как таблицы и поля в базе данных SQL. Написание кода Пролога в процедурном стиле похоже на покупку Феррари для использования в качестве трактора :-)
Как обычно, самая сложная часть изучения нового языка — это перенастроить ваш мозг на мышление в стиле этого языка. Я буду иметь это в виду в дальнейшем.
Вы усложняете свою жизнь, используя имена переменных X, Y и Z, а не осмысленные имена, такие как Мать, Отец, Дитя.