2010-06-03 2 views
9

Оператор трубы в прологе возвращает один или несколько атомных головок и список хвостов.Что оценивает [a | b | c] в SWI-Prolog?

?- [a,b,c] = [a,b|[c]]. 
true. 

Вложение нескольких труб в одной игре можно сделать примерно так:

?- [a,b,c] = [a|[b|[c]]]. 
true. 

Что делает заявление [a|b|c] Infer о, Ь и с?

EDIT

До сих пор все, что я могу вывести это:

?- [a,b,c] = [a|b|c]. 
false. 

Я больше заинтересован в любых методах найти ответ, а не отвечать на этот вопрос пограничного бесполезный.

EDIT2
Я явно не слишком хорошо знаком с прологом, простое задание ответило на мой вопрос ...

?- R = [a|b|c]. 
R = [a| (b'|'c)]. 

Что именно происходит с (b'|'c)?

+1

Похоже, домашнее задание для меня. Если да, отметьте это как таковое. –

+3

Я не знаком с Prolog, но, ну, почему вы не можете просто написать краткую программу для ее оценки? – Matchu

+3

На самом деле нет, просто интересный вопрос, на который я наткнулся, изучая экзамены на семестр на uni: https://secure.csse.uwa.edu.au/run/help3242?p=np&a=99 Я потратил некоторое время мой вопрос, чтобы выглядеть красиво, хотя, подходит для экзаменационной работы? :) – Ambrose

ответ

9

Поскольку я Ваш лектор I, вот мой ответ.
(О, и я могу подтвердить, что это не домашнее задание, это связано с практическим экзаменом).

Синтаксис [a|b|c] фактически не является стандартным прологом, а некоторые реализации интерпретируют его по-разному. (Если бы я знал это, я бы, возможно, не использовал его.)

Некоторые интерпретируют его как [a|[b|c]]. (Как я предполагал.)

Но с SWI Prolog (и, возможно, другие):

?- [a|b|c] = [a|[b|c]]. 
false. 

(b '|' c) фактически построена с использованием '|', а не '.' как список будет.Таким образом, второй | не интерпретируется как часть построения списка вообще.

Чтобы подтвердить это, следующие преуспевает:

 
    ?- X=(b|c), [a|b|c] = [a|X]. 
    X = (b'|'c) . 

'|' здесь кажется другим бинарным оператором на условиях так же, как '.'.

Вместо [a|b|c] стандартом в Prolog является использование [a,b|c].

(я только решил использовать [a|b|c] в Парадигмы программирования, потому что он более непосредственно относится к обозначениям a::b::c от F #, и мы видели только небольшое представление о Прологе. В будущем я думаю, я буду относиться к [a|[b|c]], а затем дать [a,b|c] как аббревиатура.)

+0

О, верно! Поэтому '[a | b | c]' является синтаксическим сахаром для '.. (A, (b '|' c))'!Поэтому оператор '|' отличается от '::' тем, что хвост не обязательно должен быть списком, просто «вещью»? Я все еще пытаюсь проглотить то, что именно это означает для языка **, а не ** имеет типы ... – Ambrose

+1

Технически '' .'' и '' | ''являются операторами. Оба могут быть применены к любым двум терминам, чтобы создать вид пары - в отличие от '::' в F #/ML, где контролер типов гарантирует, что '::' используется только для пар головы и соответствующего хвоста. '' .'' почти всегда используется для списков, а синтаксис '[t1, t2 | t3] 'является аббревиатурой для'.. '(t1,'. '(t2, t3)) '. Если 't3' на самом деле' t4 | t5' то, что '|' не является частью аббревиатуры, поэтому вы получаете '.. '(t1,'. '(t2, (t4' | 't5))). – RD1

+1

Какая система интерпретировала '[a | b | c]' как '[a | [b | c]'? Пожалуйста, см. Мой ответ на стандарт. – false

5

Это не утверждение, это термин, и это вовсе не означает ничего о a, b или c. Он просто создает неправильный список.

Чтобы уточнить: синтаксис [|] на самом деле является синтаксическим сахаром для оператора .(). Списки внутренне построены через '.'(a,[]), но так как это становится очень утомительным для ввода сразу, вам разрешено писать [a]. Таким образом, оператор . должен взять вещь и список, а затем конструировать более длинный список, но поскольку нет ввода текста, никто не мешает вам применить его к двум атомам или любой другой паре вещей. Результатом является структура, на которой некоторые операции списка преуспевают, а другие терпят неудачу. Это иногда полезно (думаю, двоичные деревья), но не так часто, как списки, поэтому нет специального синтаксиса для чтения.

(То же самое происходит и с cons оператора в Лиспе;., Если Google «неправомерный список» Вы обязаны получить много больше результатов о Лиспе, но принцип точно такие же)

+0

Отличный ответ, спасибо! Любой шанс, что вы могли бы дать мне указатель на мое второе редактирование вопроса, с '' | ''? – Ambrose

+0

Да, за исключением того, что в SWI Prolog (и, возможно, другие) вторая '|' не интерпретируется как «.». – RD1

5

В ISO-прологе [a|b|c] является недопустимым синтаксисом. А тем временем и в SWI. Кажется, вы использовали более старую версию. Некоторые системы Пролога дали этому термину некоторую интерпретацию. Увы, все они очень точно различали то, как они интерпретировали этот термин. Некоторые как [(a'|'b)|c] или [a|(b'|'c)] или [a|(b;c)] ... ну, вы его получите.

В связи с этим используется панель в качестве оператора инфикса ('|')/2.

С ISO/IEC 13211-1:1995/Cor.2:2012, Техническое исправление 2, опубликовано 2012-02-15 использование штрих-кода | в качестве инфиксного оператора теперь точно определено. До этого нужно было указывать |. Здесь is its draft.

Теперь '|' может быть определен как оператор инфиксного, но только с приоритетом выше 1000. Таким образом иначе неоднозначные случаи как [a|b|c] остаются синтаксический недействительными, но использует из | для DCGs и CHR является действительным.

Если вы хотите изучить синтаксис, попробовав его, лучше всего использовать writeq/1 и write_canonical/1.

Наиболее подходящая система w.r.t Синтаксис ISO-Prolog - это GNU Prolog.

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