Використовуйте арифметичні оператори як кортежні конструктори і мінуси
Якщо вам потрібно передати одну структуру, що складається з двох або більше значень, найбільш очевидним, що слід використовувати, є список, наприклад [A,B]
. Це справді багатослівно.
Є альтернатива. Значення Prolog можуть зберігати досить багато довільної вкладеної структури, яка не оцінюється. Ось приклад, який показує, як це працює:
| ?- member(member(A,B),C).
C = [member(A,B)|_] ? ;
C = [_,member(A,B)|_] ? ;
(etc.)
member(A,B)
є лише названим кортежем у цій ситуації, і зовні member
(що є викликом функції) трактується як такий.
Хоча названі кортежі досить корисні в програмі Prolog, що не використовується для гольфу, вони можуть здатися ще більш багатослівними, ніж підхід до списку. Однак ми можемо використовувати досить багато довільних символів в імені конструктора кортежів (якщо припустимо, що вони цитуються належним чином); замість чогось подібного милого member
або одного персонажа, як a
ми, можемо зробити щось подібне:
| ?- A = '-'('/'(1,2), '/'(3,4)).
A = 1/2-3/4
Ось наші конструктори кортежів є '-'
і '/'
. І цікаво відзначити, що зробив з ними симпатичний принтер; він використовує позначення інфіксів для кортежів. Це дійсно коротко і аналізує так само, як і порівняльна арифметична операція. (Це також пояснює, чому використання арифметики is
не використовується =
; A = 1+2
було б уніфіковано A
з кортежем '+'(1,2)
, тому потрібен окремий синтаксис, щоб фактично оцінити неоцінений арифметичний вираз.) Оскільки конструктор кортежу повинен називатися чимось, , ви можете також використовувати символ, який має терс синтаксис (і як бонус, -
і/
є одним із найпоширеніших варіантів у коді, який не використовується для гольфу, коли вони хочуть швидкого конструктора, що викидається, а не чогось значущого, майже таким же чином, якийi
часто використовується як циклічна змінна, тому їх цілком розумно використовувати при введенні та виведенні, якщо вам здається, що з якоїсь причини потрібен кортеж).
'-'
і '/'
є гарним вибором для кортежних конструкторів, оскільки вони мають добре поводитися та корисні переваги, дозволяючи вам писати кортежні букви буквально. Однак зауважте, що вам не потрібно турбуватися про перевагу, коли проміжні значення виробляються всередині програми. Prolog зберігає кортежі, які зберігаються як дерево, а не як вихідний код, і симпатичні принтери можуть виводити його однозначно:
| ?- A = '-'('-'(1,2), '-'(3,4)).
A = 1-2-(3-4)
Тому що синтаксис кортежу настільки лаконічний ( f(A,B)
не коротший заf(A-B)
), ви можете безкоштовно замінити кілька аргументів передбачення кортежами, тобто якщо предикату потрібно передати два чи більше його аргументів іншому предикату, ви можете часто їх формувати кортеж і просто передати кортеж (хоча це потребує зміни всіх викликів до присудка, крім самого присудка, використовувати відповідну суміш конструкторів кортежу та коми).
Ще одна перевага цього синтаксису полягає в тому, що вам потрібно використовувати списки внутрішньо (а не взаємодіяти зі стандартними предикатами); список - це лише набір вкладених комірок проти, а комірка проти - це лише кортеж із конструктором '.'
, як це видно тут:
| ?- Q = '.'('.'(A,B),'.'(C,D)).
Q = [[A|B],C|D]
Якщо ваш код використовує списки "вручну", то може використовувати багато сенсу використовувати менш об'ємний конструктор кортежів, ніж '.'
. Поширений вибір для мене полягає в тому, щоб представити мінусову клітинку як '/'(Tail,Head)
(бо мова йде про найбільш читабельний, який ви можете отримати у виведенні налагодження, не витрачаючи символів). Зауважте, що ви, ймовірно, хочете і власного []
еквівалента; ви могли б використовувати[]
але це два байти, і є багато однобайтових атомів (усіх малих літер), які ви можете використовувати замість цього.
Так, наприклад, наступний список:
[1,2,3]
можна перетворити в ручне подання у такій же кількості символів, як ця:
x/3/2/1
при цьому отримуючи перевагу в тому, що [H|T]
поєднання шаблону стилю тепер можна писати більш коротко T/H
, а тест проти порожнього списку як раз, x
а не довший []
. (Звісно, це приходить з очевидним недоліком , що member
, append
і т.д., не буде працювати на цій виставі.)
prolog
Тег цікаве марно. Якщо у нас є виклик Interpret Prolog, він нам не потрібен.