[ /b/ /u/ /rf/ /dt/ /vg/ /r/ /cr/ /lor/ /mu/ /oe/ /s/ /w/ /hr/ ] [ /a/ /ma/ /sw/ /hau/ /azu/ ] [ /tv/ /cp/ /gf/ /bo/ /di/ /vn/ /ve/ /wh/ /fur/ /to/ /bg/ /wn/ /slow/ /mad/ ] [ /d/ /news/ ] [ Главная | Настройки | Закладки | Плеер ]

Ответ в тред 3812. [Назад]
 [ Скрыть форму ]
Имя
Не поднимать тред 
Тема
Сообщение
Капча Капча
Пароль
Файл
Вернуться к
  • Публикация сообщения означает согласие с условиями предоставления сервиса
  • В сообщениях можно использовать разметку wakabamark
  • На данной доске отображаются исходные имена файлов!
  • Разрешенные типы файлов: code, vector, text, image, archive
  • Тред перестает подниматься после 500 сообщений.
  • Треды с числом ответов более 100 не могут быть удалены.

No.3812 Ответ
Файл: 1277844964859.jpg
Jpg, 50.94 KB, 450×428 - Нажмите на картинку для увеличения
edit
1277844964859.jpg
Привет
Есть такого сорта задача.

Имеется множество цифр, записанных в определённом порядке, имеется множество
одно- и двухместных операций. Оставляя неизменным порядок цифр, пользуясь
скобками и вышеназванными операциями, составить список всевозможных комбинаций
и соответствующих результатов.

Продолжение в комментах
>> No.3813 Ответ
Скажу сразу, от функциональщины я довольно далёк. Прочитав первые ~100
страниц RWH, LYAH, вдоволь набаловался ghci и в общем-то так и не понял, на кой
хуй это ебота нужна.
И вот вдруг однажды столкнулся я с такой вроде бы лёгкой задачкой - мол, ну
перебор и перебор, потыркаю там циферки и готово, я ж блять книжки почитал и
теперь горы сверну, но, почирикав немного на листочке, поприкидовав как бы это
всё дело более не менее адекватно сформулировать, жиденько обосрался.

Начнём с простейшего

Есть три цифры - [X, Y, Z]. Есть такие бинарные операторы - сложение(+),
вычитание (-), конкатенация (^, к примеру, из 1 и 2 получить 12). Унарные -
только отрицание (-).

Для этого случая унарным отрицанием можно пренебречь - просто сделать
опциональным отрицание первой цифры X и всё. Тогда список комбинаций
представляется довольно прозрачным:
X + Y + Z
X + Y - Z
X + Y ^ Z
X - Y + Z
X - Y - Z
X - Y ^ Z
X ^ Y + Z
X ^ Y - Z
X ^ Y ^ Z
-X + Y + Z
-X + Y - Z
-X + Y ^ Z
-X - Y + Z
-X - Y - Z
-X - Y ^ Z
-X ^ Y + Z
-X ^ Y - Z
-X ^ Y ^ Z

Ок, но блять, как это считать? Если учитывать приоритеты, а их учитывать стоит,
потому как конкатенация приоритетом выше остальных операций, то получается что
проще использовать префиксную запись. А из такой записи, используя scm, неким
образом возможно посчитать результат.

Проблема 1: каким образом возможно составить те же 9 выражений (принимая за
данность то, что первый операнд будет сначала X, а потом (-X)) в префиксной
записи?

Жутко анноит то, что уже даже для самой простой версии событий получается некий
непредставимый в голове кал. Соответственно, печально думать, с какими
трудностями придётся столкнуться, когда придётся использовать больше унарных
операций вроде факториала, а того хуже скобки, с коими в начальной версии
проблем не было из-за их ненадобности.

Проблема 2: действительно ли возможно будет сформулировать все возможные
выражения в префиксной форме, принимая во внимание то, что придётся иметь дело
с унарными операциями?
>> No.3814 Ответ
>>3812
> одноместных операций
> всевозможных комбинаций
Лолшто?

op(...op(op(op(x)))...)
>> No.3815 Ответ
Файл: 125636138064516.png
Png, 75.70 KB, 698×658 - Нажмите на картинку для увеличения
edit
125636138064516.png
>>3813
> в голове кал
И правда. Перечитал твой псто еще раз - ты же всё делаешь неправильно. Начиная с хаскеля и заканчивая рассуждениями о приоритетах, скобках и *фиксности.
>> No.3816 Ответ
>>3814
Одноместная операция = унарный оператор. К примеру - sgn(определение знака), факториал, чётность числа, етц...

Хуйню про оп(оп(оп( не понял
>> No.3817 Ответ
>>3816
> Одноместная операция = унарный оператор
Ах воооот оно што!
> Хуйню про оп(оп(оп( не понял
sgn(sgn(sgn(.....
Так понятней?
>> No.3818 Ответ
>>3815
Вполне возможно. Если бы ты поправил, было бы отлично.
>> No.3819 Ответ
>>3817
Сама запись понятна, конечно, но непонятно к чему это?

Если ты о том, что количество вариаций может быть бесконечно, то как видно по начальному примеру, все выражения составляются по принципу вставки между символами цифр (операндов) символов операторов и скобок.
>> No.3820 Ответ
Файл: 1239584956162.png
Png, 42.91 KB, 275×300 - Нажмите на картинку для увеличения
edit
1239584956162.png
>>3819
Не будь таким тупым же. Если разрешены унарные операторы, то как ни подставляй, формул будет бесконечно много.

В любом случае попробуй написать для бинарных. Соснешь же.
>> No.3821 Ответ
>>3820
В том-то и дело, что я уже не знаю как это написать в префиксной форме даже только для двухместных функций.

Как уже говорилось, те 9 строк генерировать нетрудно, но когда появляются скобки начинается пиздец.
>> No.3822 Ответ
>>3821
> 9 строк генерировать нетрудно
Где код?
> в префиксной форме
Не имеет значения.
> появляются скобки
Скобки вообще не нужны. Сюрприз?
>> No.3823 Ответ
>>3822
Не имеет значения что? Использование префиксной или постфиксной?
Если вертеться между ними двумя, то скобки не нужны, да, насколько я понимаю.

И потом. Эти сраные девять строк теряют очевидную закономерность будучи записаны иначе.
(+ (+ X Y) Z) (- (+ X Y) Z) (+ (^ Y Z) X) (+ (- X Y) Z) (- (- X Y) Z) (- X (^ Y Z)) (+ (^ X Y) Z) (- (^ X Y) Z) (^ X (^ Y Z) ) То есть, как их нагенерировать - нихуя не ясно. Реквестирую помощи.
>> No.3824 Ответ
>>3823
> Реквестирую помощи
Начни с простого, попробуй осознать, что твой "оператор конкатенации" на самом деле никакой не оператор. Ты сам себя запутал введя это слово. Напиши генератор разбиений последовательности на одну, две, три,.... N подпоследовательностей. Каждую подпоследовательность можешь считать единым целым - резутатом это твоей конкатенации, после чего про нее смело можешь забыть.
>> No.3826 Ответ
>>3813
> в голове кал
...

и так, top-level:
1. генерируешь все комбинации расстановки скобок для твоих чисел
2. для каждой комбинации расставляешь операции и считаешь полученное выражение

по шагам:
1. расстановка скобок
делается просто: всю последовательность чисел дробим на 2,3..N частей и огораживаем/неогораживаем (перебор) их скобками. важно учесть что две неогороженные части не могут соседствовать рядом (иначе это одна неогороженная часть). т.к. мы перебираем в цикле по кол-ву частей, мы можем гарантировать отсутствие повторений.
теперь для каждой полученной огороженной скобками части повторяем процедуру, спускаясь на уровень. пределом будет кол-во чисел в части (не меньше одного числа).
таким образом получили все варианты расставить скобки
2. расстановка операций
это еще проще: изначально у тебя уже есть фиксированное кол-во мест под бинарные операции (между числами), скобки лишь изменили кол-во мест под унарные операции (тут тоже перебор).
далее полученное выражение считаешь каким-либо стандартным методом (гугель).

PS поповоду sgn(sgn(sgn: тут можно очень долго ебаться вплоть до того, что я ввожу унарную операцию f(x)=x+1, а потом пиздячу f(f(f(... и получаю бесконечное счетное множество вариантов

PPS при расчете можно учесть то, что скобки первоприоритетны и значение в них можно посчитать сразу. таким образом, значение можно толкать наверх при разбиениях в пункте 1

PPPS если мне будет не впадлу, я может быть напишу говнокот и посмотрим как оно работает
>> No.3827 Ответ
> Если разрешены унарные операторы, то как ни подставляй, формул будет бесконечно много
Будто с бинарными не так.
>> No.3828 Ответ
>>3826
Чего я не понимаю, так это какого такого хуя вы решили, что под унарные операции мест бесконечное число?
>> No.3829 Ответ
>>3826
> посмотрим как оно работает
Напиши, пожалуйста. Очень хочется посмотреть.

>>3827
Разумеется, нет. Бинарная операция на входе имеет два объекта, а на выходе один. Количество начальных объектов конечно, так что рано или поздно у тебя останется один объект, и бинарные операции будет не к чему применять.

>>3828
С того хуя, что даже имея всего одно число 42 и одну бинарную операцию факториала можно строить следующие формулы:
42, 42!, 42!!, 42!!!, 42!!!.... и так далее бесконечно долго. Неужели это сложно?>>3828
>> No.3830 Ответ
Дольше разглагольствовали.
operator(X) :- member(X, [+,-,*,/]).

split(L1, L2) :-
        length(L1, N1),
        between(1, N1, N2),
        length(L2, N2),
        append(L2, L1),
        forall(member(SubL2, L2), SubL2 \= []).

to_number(List, Number) :- to_number(List, 0, Number).
to_number([], N, N).
to_number([D|Ds], Aux, N) :-
        Aux1 is Aux*10+D,
        to_number(Ds,Aux1,N).

formula(Numbers, Formula) :- formula(Numbers, [], Formula).
formula([], [F], F).
formula([N|Ns], Ss, F) :- formula(Ns, [N|Ss], F).
formula(Ns, [S1,S2|Ss], F) :-
        operator(Op),
        S =.. [Op,S2,S1],
        formula(Ns, [S|Ss], F).


yoba(Data, Formula) :-
        split(Data, Data1),
        maplist(to_number, Data1, Numbers),
        formula(Numbers, Formula).
>> No.3831 Ответ
>>3830
Результат. Все опреции левоассоциативные и имеют обычные приоритеты, так что скобки стоят только там, где необходимо.
?- yoba([1,2,3],F), R is F, format('~w~t~15| = ~w~n',[F,R]), false.
123             = 123
1+23            = 24
1-23            = -22
1*23            = 23
1/23            = 0.0434783
12+3            = 15
12-3            = 9
12*3            = 36
12/3            = 4
1+ (2+3)        = 6
1- (2+3)        = -4
1* (2+3)        = 5
1/ (2+3)        = 0.2
1+ (2-3)        = 0
1- (2-3)        = 2
1* (2-3)        = -1
1/ (2-3)        = -1
1+2*3           = 7
1-2*3           = -5
1* (2*3)        = 6
1/ (2*3)        = 0.166667
1+2/3           = 1.66667
1-2/3           = 0.333333
1* (2/3)        = 0.666667
1/ (2/3)        = 1.5
1+2+3           = 6
1+2-3           = 0
(1+2)*3         = 9
(1+2)/3         = 1
1-2+3           = 2
1-2-3           = -4
(1-2)*3         = -3
(1-2)/3         = -0.333333
1*2+3           = 5
1*2-3           = -1
1*2*3           = 6
1*2/3           = 0.666667
1/2+3           = 3.5
1/2-3           = -2.5
1/2*3           = 1.5
1/2/3           = 0.166667
false.
>> No.3832 Ответ
>>3829
Уверен, что задача предполагает бесконечное вхуяривание операций в позицию?
> одну бинарную операцию факториала
да ну ты брось
>> No.3833 Ответ
>>3832
Заебали. Код в студию, а потом уже будешь рассказывать про "позиции".
>> No.3835 Ответ
Файл: special-olympics.jpg
Jpg, 13.85 KB, 350×236 - Нажмите на картинку для увеличения
edit
special-olympics.jpg
Кажется, я победил.
>> No.3858 Ответ
Файл: 1236694381856.png
Png, 129.79 KB, 263×370 - Нажмите на картинку для увеличения
edit
1236694381856.png
>>3830
Можно попросить пару пояснений? Да нет, я вообще нихуя не понял, начиная с того, что это за язык

тупой не заглядывающий пару суток в тред оп
>> No.3862 Ответ
>>3858
Это пролог. На самом деле программа тривиальная. Тебе проще будет поставить конпелятор и поиграться с ней самому, если хочешь разобраться.
>> No.3868 Ответ
>>3862
gprolog подойдёт?

С первого же примера всё идет не так
| ?- max (X, Y, X) :- X>Y. uncaught exception: error(syntax_error('user_input:4 (char:5) . or operator expected after expression'),read_term/3)
>> No.3869 Ответ
>>3868
> gprolog подойдёт?
Лучше взять вот этот: http://www.swi-prolog.org/
> С первого же примера всё идет не так
Две ошибки:
- В терме функтор нельзя отделять от агрументов пробелами (поймешь почему, когда доберешься до операторов), т.е. надо писать max(X,Y,X). Об этой ошибке тебе сказали.
- А об этой пока нет: ты не там пытаешься ввести определение. То, что ты вводишь после подсказки ?- интерпретируется как запрос. Т.е. твой пример это попытка доказать цель ':-'(max(X,Y,X), '>'(X,Y)), если записать термы в канонической форме. Естественно, правила с такой головой нет, так что тебя ждет ошибка. Решения два: писать определения в файле и подгружать их с помощью consult, make и прочих. Или же, если хочется из репла, так:
debian% gprolog
GNU Prolog 1.3.0
By Daniel Diaz
Copyright (C) 1999-2007 Daniel Diaz
| ?- [user].
compiling user for byte code...
max(X,Y,X) :- X > Y, !.
max(_,Y,Y).

user compiled, 3 lines read - 416 bytes written, 49459 ms

yes
| ?- max(1,2,X).

X = 2

yes
| ?- 
Ввод завершать с помощью ^D.
>> No.3870 Ответ
>>3869
Кстати, ничего магического в правилах нет. Их можно добавлять просто как термы в базу:
| ?- asserta((test(X) :- write('testing: '), write(X), nl)).

yes
| ?- test(foo(bar,baz)).
testing: foo(bar,baz)

yes
| ?- 
>> No.3871 Ответ
>>3869
Это охуенно.
Пока открыл Интуитовские лекции и книжечку И.Братко "Алгоритмы искусственного интеллекта..."

Вопрос.
| ?- [user]. Таким образом компелируется и дополняется файл user?
>> No.3872 Ответ
>>3871
> Таким образом компелируется и дополняется файл user?
Ну только не файл, а умолчальный модуль.
http://www.swi-prolog.org/pldoc/doc_for?object=section%282%2c%275.10%27%2cswi%28%27%2fdoc%2fManual%2fresmodules.html%27%29%29

Вообще с помощь квадратных скобок можно загружать файлы. Например, если у тебя есть файл test.pl в текущем каталоге, то ?- [test]. его сконпелирует и загрузит.
>> No.3873 Ответ
>>3872
Примеры книжки Бартко как раз работают в swi-* "стиле, версии" ?
>> No.3874 Ответ
>>3873
Ну, во-первых, у пролога есть iso-стандарт. Во-вторых, в подобных книгах материал изложен по существу, а не в стиле vba для чайников: "дважды кликните по круглой кнопке в левом верхнем углу экрана и увидите зеленое окошко".

Т.е. принципиальных расхождений нет, а какую-нибудь мелочь вроде тредов или сокетов посмотришь в доках (у swi охуенные доки).
>> No.4163 Ответ
>>3830
?- append(X, [1,2,3]). ERROR: Arguments are not sufficiently instantiated    Exception: (12) throw(error(instantiation_error, _G330)) ? Почему? Ведь как написано в спецификации ListOfLists must be a list of -possibly- partial lists. http://www.swi-prolog.org/pldoc/doc_for?object=append/2
Интуитивно это вроде бы понятно, но довольно размыто.

Зачем предикату formula() аккумулятор? Трейс не помогает постигнуть принципа получения из листа цифр формулы.
Как, например, учитывается 1(2-3) и 12-3, каким именно правилом?
>> No.4164 Ответ
>>4163
1*(2-3) 1*2-3
>> No.4166 Ответ
Файл: 1265826168934.png
Png, 51.78 KB, 736×736 - Нажмите на картинку для увеличения
edit
1265826168934.png
>>4163
Я уж думал, ты хуец положил на все это.
> must be a list
А у тебя не лист, а вовсе даже переменная. Вот тебе примеров:
%% во втором списке будет ровно джва элемента
?- [L1, [X,Y], L3] = LoL, append(LoL, [1,2,3,4,5,6]), writeln(LoL), false.
%% во втором списке будет как минимум джва элемента
?- [L1, [X,Y|L2], L3] = LoL, append(LoL, [1,2,3,4,5,6]), writeln(LoL), false.
> Зачем предикату formula() аккумулятор?
А это не совсем аккумулятор. Во всяком случае, когда я писал я не думал о нем как об аккумуляторе. Я сначала просто подскажу - это стек.
> Как, например, учитывается 1(2-3) и 12-3, каким именно правилом?
Никаким и в то же время всеми сразу. Прочитай про fail driven loop. В программе нету явного цикла, в котором генерировались бы формулы. Единственный явный цикл есть в formula/3, но в нем из списка чисел конструируется одна формула.
>> No.4167 Ответ
>>4166
> А это не совсем аккумулятор
formula(Numbers, Formula) :- formula(Numbers, [], Formula). formula([], [F], F). Очень даже аккумуляторно выглядит.
> Никаким и в то же время всеми сразу. Прочитай про fail driven loop.
Я представляю себе, что такое fail driven loop. Но вопрос в другом - засчёт чего появляются скобки, то есть не просто же меняются местами операторы?
Formula/3 хуячит лист чисел по порядочку - первый элемент со вторым, в первом может быть как просто число, так и терм (хотя сохуйственно).
Да, левая ассоциативность - значит часть выражения слева от операторы имеет больший приоритет, чем правая. Но откуда появляются скобки? То есть, я понимаю, (1+2)*3 появится после того, как в Formula прилетело [1+2, 3]. Но тогда откуда появляется 1+2*3?

для 6 цифр и немного своих операторов не хватает памяти - пичаль
>> No.4168 Ответ
Файл: R-527409-1219759339.jpeg
Jpeg, 31.61 KB, 600×433 - Нажмите на картинку для увеличения
edit
R-527409-1219759339.jpeg
>>4167
> Но вопрос в другом - засчёт чего появляются скобки
Скобки печатает преттипринтер для красоты просто. В твоем примере 1*(2-3) 1*2-3 это два разных терма *(1, -(2,3)) и -(*(1,2), 3) соответственно. У меня поэтому и вызывали бугурт ваши беседы про скобки и приоритеты, потому что формулы - это по сути деревья и нет там никаких скобок.

А дальше ты все напутал, в первом списке всегда только числа (не задействованные на данный момент), в стеке сидят куски формулы и числа, третий аргумент до самого последнего момента - переменная. Когда первый список опустеет, а во втором останется один объект - строить дальше нечего и этот объект есть формула.
> не хватает памяти
http://www.swi-prolog.org/pldoc/doc_for?object=section%282%2c%272.18%27%2cswi%28%27%2fdoc%2fManual%2flimits.html%27%29%29
swi кстати используют в каких=то проектах связанных с семантик-вебом. Не знаю в чем там суть, но объемы данных фигурируют какие-то неебические (надо смотреть диссер Яна).
>> No.4169 Ответ
Файл: 19078pe46rtyguio0.jpg
Jpg, 216.95 KB, 648×900 - Нажмите на картинку для увеличения
edit
19078pe46rtyguio0.jpg
>>4168
> Скобки печатает преттипринтер для красоты просто. В твоем примере 1*(2-3) 1*2-3 это два разных терма *(1, -(2,3)) и -(*(1,2), 3) соответственно. У меня поэтому и вызывали бугурт ваши беседы про скобки и приоритеты, потому что формулы - это по сути деревья и нет там никаких скобок.
Я не очень представляю себе, на каком этапе получается первый терм. Мы же оперируем только с первыми двумя элементами листа formula(Ns, [S1,S2|Ss], F) :-, как при этом получается *(1, -(2,3))?
> А дальше ты все напутал, в первом списке всегда только числа (не задействованные на данный момент), в стеке сидят куски формулы и числа, третий аргумент до самого последнего момента - переменная. Когда первый список опустеет, а во втором останется один объект - строить дальше нечего и этот объект есть формула.
Почему же напутал? Стек аккумулирует формулы до тех пор, пока первый аргумент не пустой лист. formula([], [F], F). Выходит, это аккумулятор - или я неправильно понял его суть и пользу?
>> No.4170 Ответ
>>4169
> как при этом получается *(1, -(2,3))?
Пусть у нас есть список чисел [1,2,3] и мы его перегнали в стек полностью. Тогда стек выглядит так (стек растет влево).
3 2 1
Дальше сработает третье правило: достаем два элемента из стека, выбираем какой-нибудь оператор, например им оказался минус, конструируем терм и запихиваем его в стек:
-(2,3) 1
Снова работает третье правило и если оператором на этом этапе внезапно окажется умножение, ты получишь именно то, что ты хотел *(1, -(2,3)).

Тащемта получился ленивый стековый калькулятор, вместо результата-числа каждая операция пихает в стек формулу, которую потом можно скормить is/2.
> Стек аккумулирует формулы до тех пор, пока первый аргумент не пустой лист.
Не совсем. Условие оставки это не только пустой список чисел, но еще и "[F]" - в стеке должен остаться ровно один объект.

Мне кажется ты не до конца понимаешь суть бектрекинга и фейлоциклов. Процесс будет не всегда такой прямолинейный "перегнали все числа в стек и 'сплющили' все, применяя операторы", строго говоря, это даст нам всего лишь одну формулу (если ограничиться для простоты одним оператором). В какой-то момент операции переноса числа в стек и применения операторов начнут чередоваться (чтобы построить например такую формулу (в постфиксной нотации): 4 3 + 2 1 + *). А вот чтобы понять, с какого хуя они вдруг стали чередоваться, надо понимать как работает бектрекинг.
>> No.4171 Ответ
Файл: qweasdzxc.jpg
Jpg, 132.93 KB, 485×500 - Нажмите на картинку для увеличения
edit
qweasdzxc.jpg
>>4170
> ленивый
Зачем я это написал. Сейчас ведь набижит хаскиблядь и будет вопить, что я не понимаю сути ленивоты.
>> No.4172 Ответ
Файл: коната.jpg
Jpg, 47.48 KB, 500×500
Ваши настройки цензуры запрещают этот файл.
r-18g
>>4171
> Зачем я это написал.
Но, вообще-то, я все правельно написал же. Чего на всякое хаскелебыдло смотреть.
>> No.4173 Ответ
Файл: russkiy.jpg
Jpg, 42.61 KB, 500×736 - Нажмите на картинку для увеличения
edit
russkiy.jpg
>>4170
> Мне кажется ты не до конца понимаешь суть бектрекинга и фейлоциклов
Неудивительно :3

Спасибо, это всё действительно охуенно интересно.
>> No.4174 Ответ
Файл: 127579999079.jpg
Jpg, 38.94 KB, 222×260 - Нажмите на картинку для увеличения
edit
127579999079.jpg
Не рассмотрен случай, когда второй операнд при делении равен нулю. К примеру,
yoba([10,9,1,5,1,0], X), R is X. заканчивается
X = 109151*0, R = 0 ; ERROR: //2: Arithmetic: evaluation error: zero_divisor'`

divisor(_, 0, _) :- !. divisor(X, Y, Z) :- Y =\= 0, Z is X / Y. divis(X, Y, _) :- op(500, fxy, divisor). Но =../2 рушит всё и не может посчитать неарифметическое говно
ERROR: is/2: Arithmetic: divis/2' is not a function`

То есть, если необходиом использовать свои операторы - получать ответ из них через is или =.. уже невозможно? И всё надо переделать через суперпозиции предикатов?

Наверняка при делении на ноль можно ставить выход внутри Formula. Но никак не выходит чёрт побери
>> No.4175 Ответ
Файл: 1236247689777.gif
Gif, 41.33 KB, 323×380 - Нажмите на картинку для увеличения
edit
1236247689777.gif
>>4174
> Не рассмотрен случай, когда второй операнд при делении равен нулю.
А какое поведение ты хочешь? Тебе же кидают исключение, поймай его и обработай как-нибудь.
?- catch(R is 42/0, Err, write(Err)).
error(evaluation_error(zero_divisor),context((/)/2,_G421))
Err = error(evaluation_error(zero_divisor), context((/)/2, _G421)).
> :- op(500, fxy, divisor).
> Но =../2 рушит всё и не может посчитать неарифметическое говно
> олучать ответ из них через is или =.. уже невозможно?
1. op/3 не имеет отношения к твоим операторам, эта штука модифицирует парсер пролога, чтобы можно было записывать некоторые термы в инфиксном/префиксном/постфиксном виде. Это просто для красоты, и совсем не обязательно. А ты, кстати, написал какую-то хуиту. Что такое fxy?
2. =.. ничего ничего не считает и рушить тоже ничего не может. Он просто склеивает терм из списка [функтор|аргументы], или наоборот раздербанивает терм на части.
3. is можно дополнить неарифметическим говном с помощью arithmetic_function/1 http://www.swi-prolog.org/pldoc/doc_for?object=section%282%2c%274.26%27%2cswi%28%27%2fdoc%2fManual%2fextendarith.html%27%29%29
>> No.4176 Ответ
Файл: tumblr_kyyijlg0IZ1qzhl9eo1_500.jpg
Jpg, 96.79 KB, 452×700 - Нажмите на картинку для увеличения
edit
tumblr_kyyijlg0IZ1qzhl9eo1_500.jpg
>>4175
arithmetic_function/1 охуенно
> А ты, кстати, написал какую-то хуиту. Что такое fxy?
Да, надо fx.
> А какое поведение ты хочешь? Тебе же кидают исключение, поймай его и обработай как-нибудь.
Я не хочу никакое поведение - нужно просто отсечение. Formula ходит по веткам, возвращает формулу, которую уже другой предикат с помощью is считает и в один миг натыкается на деление на ноль. То есть, само ///3 вызывает throw, так?

Куда именно поставить catch?
Допустим, catch(allFormulas([4,1,3,5,2,4], X, 100), Err, write(Err)). Да, прекрасно, натыкаемся на деление на ноль, выводим ошибку и всё. А как отсчечь её, вернуться на другую ветку и продолжать вычисления?
>> No.4177 Ответ
>>4176
> отсечение
зачем ты сам себя запутываешь? Отсечение - это совсем другое. Тебе надо навелосипедлить такую логику: получаем очередную формулу и пробуем посчитать результат, если удалось, то делаем с результатом что-нибудь полезное (печатаем на экран) и переходим к следующей формуле, если нет - сообщаем о дефективной формуле и переходим к следующей.
?- formula([1,2,0],F), catch(R is F, Err, (writeln(bad_formula(F,Err)), fail)), writeln(F = R), fail.
> А как отсчечь её, вернуться на другую ветку и продолжать вычисления?
Сказать, что эта ветка фейловая, как же еще :з
Разницы нет в плане организации цикла - плохая там формула попалась или хорошая, нужно всего-то не дать исключению убежать слишком далеко и зделать нужное действие в зависимости от годноты формулы.
>> No.4178 Ответ
>>4176
> Да, надо fx.
Нет же. Смотри как определены уже существующие операторы. А еще лучше забей на них пока совсем, это всег лишь рюшечки.
>> No.4182 Ответ
>>4178
Да, я забил, arithmetic_function/1 вполне устраивает
>> No.4183 Ответ
Ещё вопрос.
Допустим, предикат Predicat(X1, X2, X3) возвращает массу значений. Но сами они мне неинтересны, важен лишь факт их наличия.
Каким образом можно получить количество возможных аргументов предикатов, возвращающих true?
Пока я навелосипедил сраньё в файл, затем подсчёт количества строк - мерзко, убого и медленно из-за кучи аутпутов.
>> No.4184 Ответ
>>4183
?- findall(1,operator(_),L), length(L,N).
L = [1, 1, 1, 1],
N = 4.
>> No.4186 Ответ
Ещё вопрос.

В том же хаскеле есть такая удобная вещь как sum[]. При переходах по дереву удобно собирать ответы - результат в узле равен сумме в узлах, отходящих от него, например.

Аккумулятором такую рекурсию не реализовать вроде. Как быть?
>> No.4187 Ответ
>>4186
Не понел, про какую хаскелефункцию ты говоришь. Давай линк.
> Аккумулятором такую рекурсию не реализовать вроде. Как быть?
Ты хочешь зделать обход дерева хвосторекурсивной функцией? Стандарный прием с аккумулятором работает, только аккумулировать нужно сами ветки дерева, которые еще предстоит обработать. Аккумулятор при этом выглядит как стек. У Братко, вроде бы были примеры на эту тему.
>> No.4188 Ответ
>>4187
> Не понел, про какую хаскелефункцию ты говоришь. Давай линк.
http://www.haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Prelude.html#v%3Asum
>> No.4190 Ответ
>>4188
Тогда я не понел, причем тут дерево.
>> No.4200 Ответ
>>4190
f 0 _ = 0
f фыва фыва = sum[ f фапр арва ]

Нутыпонел
Выходит, что функция вычисляется не просто через себя, а распахивается в виде дерева, а потом собирается вся в кучу
>> No.4205 Ответ
Файл: 1247604121934.jpeg
Jpeg, 14.35 KB, 286×415 - Нажмите на картинку для увеличения
edit
1247604121934.jpeg
Бородатый Емаксер, можешь оставить какой-нибудь свой фейкожид или адрес чятика, где ты обитаешь?
>> No.4206 Ответ
Файл: 125683602871801.jpg
Jpg, 111.57 KB, 588×441 - Нажмите на картинку для увеличения
edit
125683602871801.jpg
>>4205
Твой пикрелейтед сделал меня пикрелейтед.

А зачем тебе? Фейков у меня нет, я или ридонли, или анонимус, или под ирл именем пишу.
>> No.4207 Ответ
>>4206
Ну удобнее так, я на чанах не частый гость.

Вопросов куча, я бы с радостью тебя ими утомлял :3

c: советовали пора
>> No.4208 Ответ
Файл: 1257817903138.jpg
Jpg, 27.65 KB, 303×404 - Нажмите на картинку для увеличения
edit
1257817903138.jpg
>>4207
Звучит не очень заманчиво, если честно. Утомляй уж тут, пока я окончательно не съебал с чанов. inb4: Добро пожаловать. Снова.
>> No.4209 Ответ
Файл: 12682018170612500.jpg
Jpg, 20.46 KB, 280×336 - Нажмите на картинку для увеличения
edit
12682018170612500.jpg
>>4208
Ок
We shall say that an n-digit number is pandigital if it makes use of all the digits 1 to n exactly once; for example, the 5-digit number, 15234, is 1 through 5 pandigital.
The product 7254 is unusual, as the identity, 39 × 186 = 7254, containing multiplicand, multiplier, and product is 1 through 9 pandigital.
Find the sum of all products whose multiplicand/multiplier/product identity can be written as a 1 through 9 pandigital.
Собственно, перебираю все перестановки, проверяю их на факт наличия такого свойства.
Самих перестановок 9!, всех вариантов получается 28 * 9!
Но почему-то работает ажно медленно.
http://ideone.com/cP9f9
В каком месте я прошляпился?
>> No.4212 Ответ
>>4209
> В каком месте я прошляпился?
Первым делом в наивном алгоритме.

Если же считать, что алгоритм годный и судить только о программе, то суть токова: слишком много повторных вычислений:
1. выкинуть сплит/шаттер - это просто вредительство какое-то, гораздо проще это делается так (List = [[_|_],[_|_],[_|_]], append(List,X)) 2. еще лучшей идеей будет попробовать развернуть маплист руками и делать два append/3 вместо одного append/2. Посмотри как генерируются разбиения: первый подсписок остается неизменным пока элементы перегоняются по одному из третьего во второй и каждый раз ты пересчитываешь листТуНамбер для первого подсписка.
3. Не вычислять симметричные произведения: потребовать, чтобы первый множитель не превосходил корня из произведения.
4. Посмотреть на разбиения внимательно и увидеть, что из 28-ми годными являются только два с учетом предыдущего пункта
5. Попробовать сначала генерировать разбиения, а потом их перестановки и останавливать как можно раньше (там в задаче нужно знать только сами рузультаты умножений причем без повторов).
Вот тебе вариации на тему последних двух пунктов:
isEqual_v34(M1*M2=P) :-
        permutation(X, [1,2,3,4,5,6,7,8,9]),
        L3 = [_,_,_,_],
        append(L12, L3, X),
        listToNumber(L3, P),
        ( L1=[_],   L2=[_,_,_,_]
        ; L1=[_,_], L2=[_,_,_]
        ),
        append(L1, L2, L12),
        listToNumber(L1, M1),
        listToNumber(L2, M2),
        P =:= M1 * M2.

%%%%%%%

k_permutation([],L,L).
k_permutation([X|Xs], L, L1) :- select(X,L,Lx), k_permutation(Xs,Lx,L1).

isEqual_v5(M1*M2=P) :-
        L = [1,2,3,4,5,6,7,8,9],
        L3 = [_,_,_,_],
        k_permutation(L3, L, L12),
        listToNumber(L3, P),
        call((
              ( L1=[_] ; L1=[_,_] ),
              k_permutation(L1, L12, L2),
              listToNumber(L1, M1),
              permutation(L2_, L2),
              listToNumber(L2_, M2),
              P =:= M1 * M2,
              !
             )).

test5 :- time(findall(P, isEqual_v5(_=P), L)), sumlist(L,N), writeln((L->N)).
>> No.4262 Ответ
Ещё вопрос. Как организовать do-while?

И вот такая задача. Есть последовательность простых чисел - лист. В ней нужно найти такой неразрывный сублист, сумма которого простое число, меньше 10^6, а длинна максимальна.
Вопрос в том, как мне ворочать сублисты? Если сумма миллион, а длина, допустим, 100 чисел, то в сублисте числа порядка 10^4. Простых чисел до десятитысяч немало, а сублистов из такого листа невероятная куча.
Как оптимально постепенно генерировать простые числа?
>> No.4268 Ответ
>>4262
Постепенно? Чем решето Эратосфена не подходит?
Единственный алгоритм решения - грубый перебор?
>> No.4272 Ответ
>>4268
Не факт, что надо ворочать непосредственно весь лист простых чисел до 10^4
Решето эратосфена, кстати, не многим лучше, чем тот же перебор до корня.
>> No.4371 Ответ
Ещё вопрос - как реализовать функцию проверки числа, является ли оно полным квадратом или нет?
>> No.4375 Ответ
Забыл про тебя совсем.
>>4262
> Как организовать do-while?
Скорее всего он тебе не нужен. Что ты собрался делать?
> И вот такая задача.
Предлагаю тебе начать с изобретения годного алгоритма.
> Как оптимально постепенно генерировать простые числа?
Опять же. Смотря как ты собрался их использовать. Можно ленивый список запилить. Пример - целые числа в заданном интервале:
nats(Nats, (From,To)) :- freeze(Nats, nats_aux(Nats, (From,To))).
nats_aux([From|Nats], (From,To)) :-
        (   From = To
        ->  Nats = []
        ;   From1 is From+1, nats(Nats, (From1,To))
        ).
>>4371
> полным квадратом
А что это?
>> No.4380 Ответ
>>4375
> > Как организовать do-while?
> Скорее всего он тебе не нужен. Что ты собрался делать?
Да, перечитал про бэктрекинг и отсечение, и всё что надо получилось.
> >>4371
> > полным квадратом
> А что это?
Предикат(X), который возвращает истину, если есть такой Y, X =:= Y*Y, Integer(Y).
>> No.4382 Ответ
Файл: 1236805991005.jpg
Jpg, 120.40 KB, 1280×720 - Нажмите на картинку для увеличения
edit
1236805991005.jpg
>>4380
> Предикат(X), который возвращает истину, если есть такой Y, X =:= Y*Y, Integer(Y).
Для прожэктэйлера тебе скорее всего должно хватить (Y is truncate(sqrt(X)), X =:= Y*Y) Как проверить, не скатываясь к флоатам, я не знат.
>> No.4390 Ответ
>>4382
Там, где он нужен был в PE, я просто проверял его мемберность в листе квадратов. Уже не нужно.

А проверялка корнем плоха, потому что на больших числах ошибка становится минимальной.
>> No.4394 Ответ
>>4375
> nats(Nats, (From,To)) :- freeze(Nats, nats_aux(Nats, (From,To))).
> nats_aux([From|Nats], (From,To)) :-
> ( From = To
> -> Nats = []
> ; From1 is From+1, nats(Nats, (From1,To))
> ).
Вот это я вообще не понял.
>> No.4395 Ответ
Файл: its_ok_ponytails.jpg
Jpg, 34.08 KB, 356×491 - Нажмите на картинку для увеличения
edit
its_ok_ponytails.jpg
>>4394
А так?
?- nats(Ns, (1,5)), member(N,Ns).
Ns = [1|_G473],
N = 1,
freeze(_G473, nats_aux(_G473, (2, 5))) ;
Ns = [1, 2|_G502],
N = 2,
freeze(_G502, nats_aux(_G502, (3, 5))) ;
Ns = [1, 2, 3|_G531],
N = 3,
freeze(_G531, nats_aux(_G531, (4, 5))) ;
Ns = [1, 2, 3, 4|_G560],
N = 4,
freeze(_G560, nats_aux(_G560, (5, 5))) ;
Ns = [1, 2, 3, 4, 5],
N = 5.

?- 
>> No.4398 Ответ
>>4395
Да, это охуенно.

Я что-то недопонимаю с форматом. Как мне вывести интовое число ровно на N клеток, с ведущими пробелами.
~Nd конечно прекрасно, но там ведущие нули. ~Nw тоже не оно.
>> No.4399 Ответ
>>4398
А, стоп
format('sum:~w~t~20| from ~w~t~30| to ~w~t~40| -> (~w elements) ~n', [Sum, F, Last, N]). Каждый символ | и стоящее перед ним число определяют ширину столбца как бы, да? И числа должны увеличиваться?
>> No.4400 Ответ
>>4399
Формат там довольно ебанут.
> определяют ширину столбца
Нет, это какбэ ограничитель. Все последующее добро будет начпечатано не ближе заданного количества символов от начала строки.
т.е. чтобы напечатать табличку нужно каждый следующий отступ рассчитывать так: ширина текущей колонки плюс величина предыдущего отступа. Если учитывать только ширину колонки все будет напечатано вплотную.
?- format('~w~t~5|~w~t~10|~w',[qwe,asd,zxc]).
qwe  asd  zxc
true.

?- format('~w~t~5|~w~t~5|~w',[qwe,asd,zxc]).
qwe  asdzxc
true.
>> No.4402 Ответ
>>4400
Ок, понятно
>> No.4486 Ответ
Допустим, для чисел из интервала (1,1000) выполняются проверки каким-нибудь предикатом до первой удачи.
Если использовать between/3, то после первого удачного, к примеру, 700, остальные 300 всё равно проверятся. Как это реализовать?
>> No.4487 Ответ
>>4486
Не понел. Надо проверить все или наоборот остановиться после первого?
once/1
   @
forall/2
>> No.4500 Ответ
>>4487
Надо остановиться после первого
>> No.4502 Ответ
>>4500
Тогда так.
?- listing(once).
:- meta_predicate once(0).

once(A) :-
	call(A), !.
>> No.4543 Ответ
Допустим, есть у меня файл file.txt с перечислением чисел примерно такого вида
1, 2, 3, 4 Как мне в переменную X загнать этот лист, чтобы X = [1, 2, 3, 4]?
>> No.4544 Ответ
Файл: 1246583399787.gif
Gif, 3.06 KB, 185×184 - Нажмите на картинку для увеличения
edit
1246583399787.gif
>>4543
It's DCG tiem!
>> No.4545 Ответ
>>4544
DCG я как раз неосилил из Learn Prolog.

Всё начинается с непонимания сути оператора ->.
>> No.4546 Ответ
>>4545
А чего там осиливать? читай стрелка - продукция, подцель в правой части - другое dcg-правило, в фигурных скобках обычные прологовские цели, отдельно болтающийся список - считывание из потока. Больше там и нет ничего.
unsigned_int(I) --> list_of_digits(Ds), { number_codes(I,Ds) }.
list_of_digits([D|Ds]) --> digit(D), !, list_of_digits(Ds).
list_of_digits([])     --> [].
digit(D) --> [D], { code_type(D, digit) }.
>> No.4547 Ответ
>>4546
Осло, если формат данных задаешь ты, можно сделать его совместимым с прологом - наопределять опрераторов и заюзать стандартный ридер.
>> No.4548 Ответ
>>4546
А фигурные скобки что значат?
> list_of_digits([D|Ds]) --> digit(D), !, list_of_digits(Ds).
Разве после отсечения что-то когда-нибудь вызовется?
>> No.4549 Ответ
>>4548
Я же написал, в фигурных скобках обычные цели, без скобок они интерпретируются как dcg.
> Разве после отсечения что-то когда-нибудь вызовется?
Ты ниасилил отсечение. Грубо говоря, отсечение предотвращает перебор клозов (clause) текущего предиката и всех подцелей левее себя в данном клозе. Отсечение удаляет так называемые точки отката, а само выполнение не прекращается. Сейчас пример сочиню.
>> No.4550 Ответ
>>4549
Пожалуй здесь все видно будет:
p(first(X)) :- bt(X).
p(second(X,Y)) :- bt(X), !, bt(Y).
p(third(_)) :- throw(unreachable).

bt(X) :- member(X, [qwe,asd,zxc]).
Результат:
?- p(X).
X = first(qwe) ;
X = first(asd) ;
X = first(zxc) ;
X = second(qwe, qwe) ;
X = second(qwe, asd) ;
X = second(qwe, zxc).
>> No.4551 Ответ
>>4550
Да.
>> No.4568 Ответ
Вот уже дней пять пытаюсь растыкать это говно и всё в пустую. http://projecteuler.net/index.php?section=problems&id=51

Алгоритм такой - сначала выбираем из всех 6-ти циферных чисел простые, причём с хотя бы 3-мя повторяющимися цифрами. Получаем лист, элементы которого - число и сама повторяющаяся цифра
Затем из листа делаем выборку из восьми элементов и проверяем, будут ли они удовлетворять определённым свойствам.
Проверялку восьми чисел нихуя не доделал, ужасное мерзкое говно.

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

Если есть числа 56003, 56113, 56333, 56443, 56663, 56773, 56993 очень чешется по запросу
numlist(0,9,Digits), member(A, Digits), X = [5,6,A,A,3] получать этот лист.

В общем, хуйня какая-то выходит как не подступись.

Что скажешь по поводу идеи - как это быстро, элегантно решать?
>> No.4597 Ответ
>>4568
Запости свой понос чтоли, с нуля лень писать.
>> No.4598 Ответ
>>4597
В том-то и дело, что почти ничего нет http://ideone.com/uxed6
>> No.4799 Ответ
>>4597
Чем всё кончилось?
>> No.4800 Ответ
Файл: x_b1714952.jpg
Jpg, 34.35 KB, 600×480 - Нажмите на картинку для увеличения
edit
x_b1714952.jpg
>>4799
Даже не начиналось. Пикрейлейтед.

Ты не придумал алгоритма получше?
>> No.5047 Ответ
Есть prolog.pl. Как в шелле применить к этому файлу свой гоал и вернуться в шелл?

swipl -s ./prolog.pl -g "N = 1, shitfuck(N, X), open(output, append, OS), format(OS, '~w~n', X), close(OS), false" После чего прологовский swipl остаётся активным, а мне его совсем не надо.

Плюс, как вместо этого N = 1 записать внутрь гоала что-то вроде N = $1 для удобного использования? Компилятор ругается.
>> No.5048 Ответ
Файл: 11f84ac314ced6524384d2642209fa26e528d6e2.jpg
Jpg, 52.08 KB, 300×300 - Нажмите на картинку для увеличения
edit
11f84ac314ced6524384d2642209fa26e528d6e2.jpg
>>5047
http://www.swi-prolog.org/pldoc/man?predicate=halt%2f0
$ MY_N=42; swipl -q -t halt -g "N=$MY_N, writeln(teh_answer(N))"
teh_answer(42)
>> No.5049 Ответ
Файл: bscap0387.jpg
Jpg, 34.34 KB, 704×396 - Нажмите на картинку для увеличения
edit
bscap0387.jpg
>> No.5077 Ответ
>>5049
Хорошее
>> No.7338 Ответ
Пролог-кун, я снова выхожу на связь.
(c: проснуться) как бы намекает
Появились вновь интересные задачи под сеё полуживое дело. Их много, посему ближайшие дни буду искать у тебя ответов.
Например.
Как мы там реализуем выборки с повторениями?
А именно, предикат, возвращающий, к примеру:
a(X, [1,2,3]).
X = [1,1,1],
X = [1,1,2],
X = [1,1,3],
X = [1,2,1],
X = [1,2,2],
X = [1,2,3],
X = [1,3,1],
X = [1,3,2],
X = [1,3,3],
.....
X = [3,3,2],
X = [3,3,3],
false.
Вроде бы проще легкого, но я запутался что-то.
>> No.7349 Ответ
Подкиньте чего-нибудь, чтобы Прологу научиться. Желательно простого, ибо я до этого только в C копался. Гугль, конечно, товарищ, но я не знаю, что из всего этого полезное/простое/нужное.
>> No.7366 Ответ
>>7338
a(X,L) :-
is_member(A,L),
is_member(B,L),
is_member(C,L),
X=[A,B,C].

is_member(X,[]) :- false.
is_member(X,L) :-
L=[X|R];
is_member(X,R).
>> No.7374 Ответ
>>7366
Не, это не общий случай.
get_set(L0, L) :-
    length(L, Len),
    length(L0, Len),
    apply_elem(L0, L).

apply_elem([], _).
apply_elem([X|Xs], L) :-
    member(X, L),
    apply_elem(Xs, L).
>> No.7375 Ответ
>>7374
можно проще же
yoba(X,L) :- yoba(X,L,L).
yoba([],[],_).
yoba([X|Xs],[_|T],L) :- member(X,L), yoba(Xs,T,L).
>> No.7377 Ответ
Мать мою, как я мог пропустить столь винрарный тред. Обожаю пролог, завтра перечитаю и отпишусь, если будет о чём.
>> No.7379 Ответ
Файл: CJ7TSZ27FH6DMWI7FNYIIF5AY63NT6B2.jpeg
Jpeg, 108.54 KB, 640×480 - Нажмите на картинку для увеличения
edit
CJ7TSZ27FH6DMWI7FNYIIF5AY63NT6B2.jpeg
>>7375
Бородач, ты?
>> No.7386 Ответ
Годный тред, после сплошного тупняка как глоток свежего воздуха. Узнал, что в swipl есть куча полезных не-ISO расширений, буду изучать.

Алсо, Бородатый, расскажи немного о себе. Ты, как я понимаю, на Прологе пишешь какие-то реальные задачи, или это всё же just fot fun ?
>> No.7389 Ответ
>>7375
Мне одному кажется, что можно было обойтись и без yoba/3 ?
>> No.7390 Ответ
>>7389
Можно было вообще обойтись без всего.
>> No.7428 Ответ
>>3812
ТРЕД НЕ ЧИТАЙ@СРАЗУ ОТВЕЧАЙ
(c:решать прежде)
Няша оп, у тебя все получится. Перебери (рекурсивно) все возможные деревья бинарных сочетаний, и перебери все варианты расстановки операций в узлах.
Унарные операции ставятся и в узлах, и в листьях. Как тут уже указывали, с ними будет OVER +inf решений.
Если только с бинарными, то я сейчас ради разминки написал программу на хаскеле на перемене до завтрака. Как-то так:
main = mapM (putStrLn . show) $enumerate [1,2,3,4]
data BinOp = Add | Sub | Mul | Div deriving Enum
instance Show BinOp where
    show Add = "+"
    show Sub = "-"
    show Mul = "*"
    show Div = "/"
data Fractional a => Tree a = Leaf a | Knot BinOp (Tree a) (Tree a)
instance (Show a,Fractional a) => Show (Tree a) where
    showsPrec ord (Leaf a) s = showsPrec ord a s
    showsPrec ord (Knot f a b) s = '(':showsPrec ord a (showsPrec ord f $showsPrec ord b $')':s)
enumerate :: Fractional a => [a] -> [Tree a]
enumerate [] = []
enumerate [a] = [Leaf a]
enumerate operands = do
            n <- [1 .. length operands - 1]
            let (lefts,rights) = splitAt n operands
            left <- enumerate lefts
            right <- enumerate rights
            op <- [Add .. Div]
            return $Knot op left right
%%Алсо ассоциативности операций при таком подходе не существует, a+(b+c) != (a+b)+c, лол.
>> No.7729 Ответ
Файл: tumblr_lf2hpfbXso1qfb9ubo1_400_large.jpg
Jpg, 82.66 KB, 400×400 - Нажмите на картинку для увеличения
edit
tumblr_lf2hpfbXso1qfb9ubo1_400_large.jpg
Пролог-куны, спасайте.
Попробовал описать односвязный напраленный граф - и соснул для самого маленького примера.
Граф задаётся листом пар [a,b] - рёбра (a,b). Порядок, повторяю, важен.

clear_link(X, Y, RelationList) :-
    (member([X,Y], RelationList)
    ;
    member([Y,X], RelationList)),
    X =\= Y.

linked(X, Y, RelationList) :-
    clear_link(X, Y, RelationList),
    !.
linked(X, Y, RelationList) :-
    clear_link(X, Z, RelationList),
    linked(Z, Y, RelationList).

simple_connect(RelationList, E) :-
    forall((member(X, E),
    member(Y, E), X < Y),
    linked(X, Y, RelationList)).
?- simple_connect([[2,1],[2,3],[4,3],[4,5],[6,5]],[1,2,3,4,5,6]).
ERROR: Out of local stack
>> No.7732 Ответ
>>7729
Потому что наивный поиск в глубину будет зацикливаться на циклическом графе, надо поддерживать множество уже пройденных вершин.
>> No.7736 Ответ
>>7732
Стек оверфловится и для нецикличного графа
>> No.7737 Ответ
>>7736
Вот с этим у тебя любой граф будет циклический:
   (member([X,Y], RelationList)
    ;
    member([Y,X], RelationList))
>> No.7738 Ответ
Файл: 1220034371056.jpg
Jpg, 3.67 KB, 143×200 - Нажмите на картинку для увеличения
edit
1220034371056.jpg
>>7737
Што

RelationList - лист ребёр
clear_link/2 - предикат связи 2 точек (есть ребро A→B или ребро B→A).

И да, проверяться будут только нецикличные графы, потому как это на самом деле не граф вовсе, а частично упорядоченное множество с бинарным отношением над ним.
>> No.7739 Ответ
>>7738
На словах у тебя лев толстой, а в коде хуй простой. То, что я процитировал, фактически дублирует каждое ребро в обратном направлении. Если ты явно указал ребро [1,2], то неявно у тебя появится еще и [2,1]. Поэтому на самом деле в твоем графе сотни циклов.
> частично упорядоченное множество с бинарным отношением над ним
масло масляное :3
>> No.7748 Ответ
>>7739
Да, я понял твою мысль. Верно :3
Поправил, теперь всё ок
clear_link(X, Y, RelationList) :-
    member([X,Y], RelationList),
    X =\= Y.

linked(X, Y, RelationList) :-
    clear_link(X, Y, RelationList),
    !.
linked(X, Y, RelationList) :-
    clear_link(X, Z, RelationList),
    linked(Z, Y, RelationList),
    !.

simple_connect(RelationList, E) :-
    forall((member(X, E),
    member(Y, E), X < Y),
    linked(X, Y, RelationList)).

connective_graph(RelationList, E) :-
    findall(Relation, (
        member(X, RelationList),
        sort(X, Relation)
    ),SortRelationList),
    simple_connect(SortRelationList, E).
Например,
?- connective_graph([[2,1],[2,3],[4,3],[4,5],[6,5]],[1,2,3,4,5,6]).
true.

?- connective_graph([[2,1],[4,3],[4,5],[6,5]],[1,2,3,4,5,6]).
false.
>> No.7930 Ответ
Файл: x_1ca92f2b.jpg
Jpg, 34.95 KB, 377×437 - Нажмите на картинку для увеличения
edit
x_1ca92f2b.jpg
>>7748
М
Я тут наврал, кстати.

Вот верный вариант есличо
connected(X, Y, RelationList) :-
    (member([X,Y], RelationList);
    member([Y,X], RelationList)).

path(X, Y, RelationList, Path) :-
    travel(X, Y, RelationList, [X], ReversePath),
    reverse(ReversePath, Path),!.

travel(X, Y, RelationList, Point, [Y | Point]) :-
    connected(X, Y, RelationList).
travel(X, Y, RelationList, Visited, Path) :-
    connected(X, Z, RelationList),
    Z =\= Y,
    \+member(Z, Visited),
    travel(Z, Y, RelationList, [Z|Visited], Path).

connective_graph(RelationList, E) :-
    forall((member(X, E),
        member(Y, E),
        X < Y)
    ,path(X,Y,RelationList,_)).
>> No.7932 Ответ
>>7930
Каркуша даже круче Гаечки, натоящая Богиня, дискасс.
>> No.7943 Ответ
>>7932
 
И rule34 на нее нету


Пароль:

[ /b/ /u/ /rf/ /dt/ /vg/ /r/ /cr/ /lor/ /mu/ /oe/ /s/ /w/ /hr/ ] [ /a/ /ma/ /sw/ /hau/ /azu/ ] [ /tv/ /cp/ /gf/ /bo/ /di/ /vn/ /ve/ /wh/ /fur/ /to/ /bg/ /wn/ /slow/ /mad/ ] [ /d/ /news/ ] [ Главная | Настройки | Закладки | Плеер ]