2014 dxdy logo

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

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




На страницу Пред.  1, 2
 
 Re: Первые шаги в ПРОЛОГе
Сообщение12.05.2014, 19:32 
Аватара пользователя
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 
Аватара пользователя
Есть проблемс.
Вот код:
код: [ скачать ] [ спрятать ]
Используется синтаксис 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 
А что такое atom_string?

 
 
 
 Re: Первые шаги в ПРОЛОГе
Сообщение23.05.2014, 13:13 
Аватара пользователя
Pphantom
http://www.swi-prolog.org/pldoc/man?pre ... m_string/2
Двунаправленная конвертация между атомом и строкой. Первый аргумент - атом, второй - строка

 
 
 
 Re: Первые шаги в ПРОЛОГе
Сообщение23.05.2014, 22:57 
SamGold в сообщении #866901 писал(а):
Двунаправленная конвертация между атомом и строкой. Первый аргумент - атом, второй - строка
Спасибо. У меня была сравнительно более старая версия, там этого предиката нет.

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

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

 
 
 
 Re: Первые шаги в ПРОЛОГе
Сообщение12.06.2014, 22:59 
Аватара пользователя
Вот код. Может кому-нибудь пригодится
код: [ скачать ] [ спрятать ]
Используется синтаксис 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 
Аватара пользователя
Решил задачу другим способом. Вот:
код: [ скачать ] [ спрятать ]
Используется синтаксис 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 
Аватара пользователя
Решение найдено. Чуть позже скину код

 
 
 [ Сообщений: 23 ]  На страницу Пред.  1, 2


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group