2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2
 
 Re: Первые шаги в ПРОЛОГе
Сообщение12.05.2014, 19:32 
Аватара пользователя


30/04/14
26
Pphantom в сообщении #861277 писал(а):
сортировка и значение со средним номером

В общем, вот как я это решил:
код: [ скачать ] [ спрятать ]
Используется синтаксис Prolog
%Удаление повторяющихся элементов
remreps([H|T],[H|T1]):-
 removeall(T,H,T2),
 remreps(T2,T1).
remreps([],[]).

%Объединение списков
append([],L,L).
append([X|T],L2,[X|L3]):-
 append(T,L2,L3).

%Наивная сортировка
sortn(L1, L2) :- permutation(L1, L2), sorted(L2), !.

%Различные комбинации из элементов списка
permutation(L, [H|T]) :- append(V, [H|U], L),
append(V, U, W),
permutation(W, T).
permutation([], []).

%Проверка на "отсортированность"
sorted([L]).
sorted([X,Y|T]) :- order(X,Y), sorted([Y|T]).
order(X, Y) :- X =< Y.

%Медиана такая медиана =)
mediana(L1,X):-
 remreps(L1,L2),
 sortn(L2,L3),
 fnmax(L3,N),
 D is N mod 2,
 D =\= 0,
 N1 is (N+1)/2,
 fn(L3,X,N1).

Проблема, в общем то, была в том, что видя перед собой с-образный код решения этой задачи, я никак не мог перестроить мышление на декларативный подход.
Pphantom, спасибо Вам за ценные комментарии по исцелению от симптомов быдлокодерства ))

 Профиль  
                  
 
 Re: Первые шаги в ПРОЛОГе
Сообщение23.05.2014, 11:29 
Аватара пользователя


30/04/14
26
Есть проблемс.
Вот код:
код: [ скачать ] [ спрятать ]
Используется синтаксис Prolog
notSep(C,B):-
 C=\=",",
 C=\=" ",
 C=\=".",
 C=\=";",
 C=\="-",
 C=\="!",
 C=\="?",
 B is 1,
 !.

notSep(_,0).

frontchar(S,C,SS):-
 atom_string(S1,S),
 name(S1,[H1|T1]),
 name(C1,[H1]),
 name(SS1,T1),
 atom_string(C1,C),
 atom_string(SS1,SS).


%Количество разделитлей в строке
%(пока не допилено до подсчёта
%количества слов, но это только
%усложнит разбор кода на предмет
%ошибки на данном этапе)
wordNum("",N,R):-
 R is N,
 !.

wordNum(S,N,R):-
 frontchar(S,C,SS),
 notSep(C,B),
 B>0,
 wordNum(SS,N,R).

wordNum(S,N,R):-
 frontchar(S,C,SS),
 N1 is N+1,
 wordNum(SS,N1,R).

 


В ответ на запрос:
?- wordNum("",0,R).
R = 0.
всё оКей.
А вот на все остальные - унылый false:
?- wordNum("lol",0,R).
false.

?- wordNum("lol,ololo",0,R).
false.

?- wordNum(",",0,R).
false.


P.S. Проход по алгоритму с карандашиком, только убедил меня в его корректности. А вот компилятор, всё таки, другого мнения.

 Профиль  
                  
 
 Re: Первые шаги в ПРОЛОГе
Сообщение23.05.2014, 12:06 
Заслуженный участник


09/05/12
25179
А что такое atom_string?

 Профиль  
                  
 
 Re: Первые шаги в ПРОЛОГе
Сообщение23.05.2014, 13:13 
Аватара пользователя


30/04/14
26
Pphantom
http://www.swi-prolog.org/pldoc/man?pre ... m_string/2
Двунаправленная конвертация между атомом и строкой. Первый аргумент - атом, второй - строка

 Профиль  
                  
 
 Re: Первые шаги в ПРОЛОГе
Сообщение23.05.2014, 22:57 
Заслуженный участник


09/05/12
25179
SamGold в сообщении #866901 писал(а):
Двунаправленная конвертация между атомом и строкой. Первый аргумент - атом, второй - строка
Спасибо. У меня была сравнительно более старая версия, там этого предиката нет.

Кстати, у меня на все варианты первого аргумента выдается один и тот же универсальный ответ - 0.

Насколько я понимаю, Вы забыли обработать ситуацию, когда слово в строке заканчивается не каким-то сепаратором, а просто из-за того, что сама строка кончилась, поэтому нули и появляются.

 Профиль  
                  
 
 Re: Первые шаги в ПРОЛОГе
Сообщение12.06.2014, 22:59 
Аватара пользователя


30/04/14
26
Вот код. Может кому-нибудь пригодится
код: [ скачать ] [ спрятать ]
Используется синтаксис Prolog
wordNum(S,N,R):-
 frontchar(S,C,SS),
 notSep(C,B),
 B>0,
 wordNum(SS,N,R),!.

wordNum(S,N,R):-
 frontchar(S,_,SS),
 N1 is N+1,
 toNxtWrd(SS,SS1),
 wordNum(SS1,N1,R),!.

wordNum(_,N,N).

wordNum(S,R):-
 frontchar(S,C,_),
 isChOrDig(C,B),
 B =:= 0,
 wordNum(S,0,R),
 !.

wordNum(S,R):-
 wordNum(S,1,R).

isChOrDig(C,1):-
 C>="0", C=<"9";
 C>="A", C=<"Z";
 C>="a", C=<"z",
 !.
isChOrDig(_,0).

notSep(C,1):-
 C=\=",",
 C=\=" ",
 C=\=".",
 C=\=";",
 C=\="-",
 C=\="!",
 C=\="?",
 !.

notSep(_,0).

frontchar(S,C,SS):-
 atom_string(S1,S),
 name(S1,[H1|T1]),
 name(C1,[H1]),
 name(SS1,T1),
 atom_string(C1,C),
 atom_string(SS1,SS).

toNxtWrd(S,SS):-
 frontchar(S,C,_),
 isChOrDig(C,B),
 B>0,
 SS = S,
 !.

toNxtWrd(S,SS):-
 frontchar(S,_,S1),
 toNxtWrd(S1,SS).
 


-- 12.06.2014, 22:07 --

Условие задачи:
Вам нужно переправить через реку с помощью одного плота семью 
(мать, отца, 2­х дочерей и 2­х сыновей) и полицейского с 
заключенным. Правила: 1) На плоту могут одновременно перемещаться максимум 2 человека. 
2) Папе не разрешается находиться с дочерьми без присутствия 
матери. 
3) Маме не разрешается находиться с сыновьями без присутствия 
отца. 
4) Заключённого нельзя оставлять без полицейского ни с одним из 
членов семьи. 
5) Управлять плотом могут только полицейский и родители.

код: [ скачать ] [ спрятать ]
Используется синтаксис Prolog
%обработка условий
prsnr(L):-
 L = [prisoner],
 !.
prsnr(L):-
 member(prisoner,L),
 !,
 member(policeman,L),!.
prsnr(_).

check(L):-
 not(member(papa,L)),
 member(mama,L),
 prsnr(L),
 !,
 not(member(son1,L)),
 not(member(son2,L)),
 !.
check(L):-
 not(member(mama,L)),
 member(papa,L),
 prsnr(L),
 !,
 not(member(daughter1,L)),
 not(member(daughter2,L)),
 !.
check(L):-
 prsnr(L).

raft(L):-
 check(L),
 member(prisoner,L),
 length(L,R),
 R<3,
 !,
 member(policeman,L).
raft(L):-
 check(L),
 member(X,L),
 length(L,R),
 R<3,
 isAdult(X),
 !.

isAdult(papa).
isAdult(mama).
isAdult(policeman).

%все подсписки максимальной длины 2
sublist_2_0([H,H1|_],SL):-
 SL=[H,H1].
sublist_2_0([H,_|T],SL):-
 sublist_2_0(T,SL1),
 length(SL1,L),
 L<2,
 append([H],SL1,SL).
sublist_2_0([H|_],[H]).
sublist_2_0([_|T],SL):-
 sublist_2_0(T,SL).


%все подсписки заданной длины Len
sublist(_, _, _, Len):- Len =< 0, !, fail.
%sublist([], L, L, _).
sublist([H|_], L, [H|L], _).
sublist([H|T], L, [H|R], Len):-
  NewLen is Len - 1, sublist(T, L, R, NewLen).
sublist([_|T], L, R, Len):-
  sublist(T, L, R, Len).

%поиск в глубину с построением вершин
dfs_2_0(([], [], L, Dir), [A|_], _, [([], [], L, Dir)],(A,([], [], L, Dir))):-!.
dfs_2_0(A, VN, EN, [A|TR],[E|TRE]):-
  proliferate_2_0(A, X, E),
  not(member(X, VN)),
  not(member(E,EN)),
  dfs_2_0(X, [A|VN], [E|EN], TR, TRE).

%создание ребра (может потом из него получится женщина =))
edge(A,B,E):-
 E = (A,B).

%генерация состояний
proliferate_2_0((Left, Boat, Right, left), (Left_2, Boat_2, Right, right),E):-
  append(Left, Boat, Left_1),
  sublist_2_0(Left_1,Left_1Part),
  subtract(Left_1, Left_1Part, Left_2),
  append([], Left_1Part, Boat_2),
  raft(Boat_2),
  check(Left_2),
  edge((Left, Boat, Right, left), (Left_2, Boat_2, Right, right),E).
proliferate_2_0(([], Boat, Right1, right), ([], [], Right2, right),E):-
    !, append(Boat, Right1, Right2),
    edge(([], Boat, Right1, right), ([], [], Right2, right),E).
proliferate_2_0((Left, Boat, Right, right), (Left, Boat_2, Right_2, left),E):-
  append(Right, Boat, Right_1),
  sublist_2_0(Right_1,Right_1Part),
  subtract(Right_1,Right_1Part,Right_2),
  append([],Right_1Part,Boat_2),
  raft(Boat_2),
  check(Right_2),
  edge((Left, Boat, Right, right), (Left, Boat_2, Right_2, left),E).
%proliferate_2_0(([], [], _, right), _,_):-false,!.

%предикат для поиска кратчайшего расстояния из заданной вершины
f((A,[[],[],R,right]),_,_,Path,RPath):-
 append([(A,[[],[],R,right])],Path,RPath),
 !.
f((A,[L,B,R,Dir]),Edges,Rights,Path,RPath):-
 append([(A,[L,B,R,Dir])],Path,NewPath),
 append([R],Rights,NewRights),
 sublist(Edges,[],[([L,B,R,Dir],[L1,B1,R1,Dir1])],1),!,
 not(member(R1,NewRights)),
 f(([L,B,R,Dir],[L1,B1,R1,Dir1]),Edges,NewRights,NewPath,RPath).

%findpath([],[]).
findpath(List,Path):-
 dfs_2_0((List,[],[],left),[],[],_,E),
 !,
 findall((A,(B,C,[],D)),member((A,(B,C,[],D)),E),[(X,_)|T]),
 sublist(T,[],[(Y,_)],1),!,
 f((X,Y),E,[],[],Path).
 


findpath даёт false и меня замучал. Может быть свежий взгляд со стороны поможет?

 Профиль  
                  
 
 Re: Первые шаги в ПРОЛОГе
Сообщение19.06.2014, 22:53 
Аватара пользователя


30/04/14
26
Решил задачу другим способом. Вот:
код: [ скачать ] [ спрятать ]
Используется синтаксис Prolog
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%pocible moves
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%papa and mama moved
move((papa(X),mama(X),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B)),((papa(X_N),mama(X_N),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B_N)))):-
        otherBank(X,X_N),
        %otherBank(M,M_N),
        otherBank(B,B_N).
%papa and policeman moved
move((papa(X),mama(M),policeman(X),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B)),(papa(X_N),mama(M),policeman(X_N),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        %otherBank(Pl,Pl_N),
        otherBank(B,B_N).
%papa and son1 moved
move((papa(X),mama(M),policeman(Pl),prisoner(Pr),son1(X),son2(S2),daughter1(D1),daughter2(D2),boat(B)),(papa(X_N),mama(M),policeman(Pl),prisoner(Pr),son1(X_N),son2(S2),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        %otherBank(S1,S1_N),
        otherBank(B,B_N).
%papa and son2 moved
move((papa(X),mama(M),policeman(Pl),prisoner(Pr),son1(S1),son2(X),daughter1(D1),daughter2(D2),boat(B)),(papa(X_N),mama(M),policeman(Pl),prisoner(Pr),son1(S1),son2(X_N),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        %otherBank(S2,S2_N),
        otherBank(B,B_N).
%papa moved lonely
move((papa(X),mama(M),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B)),(papa(X_N),mama(M),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%mama and policeman moved
move((papa(P),mama(X),policeman(X),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B)),(papa(P),mama(X_N),policeman(X_N),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%mama and daughter1 moved
move((papa(P),mama(X),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(X),daughter2(D2),boat(B)),(papa(P),mama(X_N),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(X_N),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%mama and daughter2 moved
move((papa(P),mama(X),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(X),boat(B)),(papa(P),mama(X_N),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(X_N),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%mama moved lonely
move((papa(P),mama(X),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B)),(papa(P),mama(X_N),policeman(Pl),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%policeman and prisoner moved
move((papa(P),mama(M),policeman(X),prisoner(X),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B)),(papa(P),mama(M),policeman(X_N),prisoner(X_N),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%policeman and son1 moved
move((papa(P),mama(M),policeman(X),prisoner(Pr),son1(X),son2(S2),daughter1(D1),daughter2(D2),boat(B)),(papa(P),mama(M),policeman(X_N),prisoner(Pr),son1(X_N),son2(S2),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%policeman and son2 moved
move((papa(P),mama(M),policeman(X),prisoner(Pr),son1(S1),son2(X),daughter1(D1),daughter2(D2),boat(B)),(papa(P),mama(M),policeman(X_N),prisoner(Pr),son1(S1),son2(X_N),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%policeman and daughter1 moved
move((papa(P),mama(M),policeman(X),prisoner(Pr),son1(S1),son2(S2),daughter1(X),daughter2(D2),boat(B)),(papa(P),mama(M),policeman(X_N),prisoner(Pr),son1(S1),son2(S2),daughter1(X_N),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%policeman and daughter2 moved
move((papa(P),mama(M),policeman(X),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(X),boat(B)),(papa(P),mama(M),policeman(X_N),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(X_N),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).
%policeman moved lonely
move((papa(P),mama(M),policeman(X),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B)),(papa(P),mama(M),policeman(X_N),prisoner(Pr),son1(S1),son2(S2),daughter1(D1),daughter2(D2),boat(B_N))):-
        otherBank(X,X_N),
        otherBank(B,B_N).



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Equality check
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

areEqual(A,A).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Restrictions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

restricted(State):-
        %policeman and prisoner are on different banks
        areEqual(State,(_,_,A,B,_,_,_,_,_)),
        otherBank(A,B);
        %papa face to face with one of the daughters
        areEqual(State,(A,_,_,_,_,_,A,_,_));
        areEqual(State,(A,_,_,_,_,_,_,A,_));
        %mama face to face with one of the sons
        areEqual(State,(_,A,_,_,A,_,_,_,_));
        areEqual(State,(_,A,_,_,_,A,_,_,_)).


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Find path
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

bigMove(Finish,Finish,Path,_,Result):-
        append([Finish],Path,Result1),
        reverse(Result1,Result),
        !.
bigMove(Start,Finish,Path,Visited,Result):-
        move(Start,Step),
        not(restricted(Step)),
        not(member(Step,Visited)),!,
        append([Step],Visited,NewVisited),
        append([Start],Path,Path1),
        bm(Step,Finish,Path1,NewVisited,Result).
       
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

papa(left).
papa(right).

mama(left).
mama(right).

policeman(left).
policeman(right).

prisoner(left).
prisoner(right).               

son1(left).
son1(right).   

son2(left).
son2(right).   

daughter1(left).
daughter1(right).      

daughter2(left).
daughter2(right).      

boat(left).
boat(right).   

smth(papa(X),mama(X),X).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
otherBank(right,left).
otherBank(left,right).
 

Решение чудовищно не оптимальное. Вывод не помещается в консоли. Даже не знаю, что с этим делать

 Профиль  
                  
 
 Re: Первые шаги в ПРОЛОГе
Сообщение23.06.2014, 16:22 
Аватара пользователя


30/04/14
26
Решение найдено. Чуть позже скину код

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 23 ]  На страницу Пред.  1, 2

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group