Advertisement
inf926k

prolog 62

Nov 8th, 2016
411
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Prolog 7.08 KB | None | 0 0
  1. DOMAINS
  2.     stringl=string*
  3.     % в этой базе данных будут хранится факты а значении цвета вершины
  4. DATABASE - vcolors
  5.     % например, vcolor("A", "blue").
  6.     vcolor(string,string).
  7. PREDICATES
  8.     % предикат берет список string и string и будет истинен, если в этом списке есть строка, напримеръ
  9.     % contains(["AA", "asdas", "df"],"df")  -  истина
  10.     contains(stringl,string).
  11.    
  12.     % предикат берет список вершин, и возвращает список их цветов (используя бд vcolors), тоже строки
  13.     nondeterm vertsToCols(stringl,stringl).
  14.    
  15.     % предикат берет вершину в первый аргумент и во второй сует список цветов вершин, смежных с вершиной - первым аргументом
  16.     nondeterm connects_cols(string,stringl).
  17.    
  18.     % просто предикат для вершин
  19.     nondeterm vertex(string).
  20.     % просто предикат для цветов
  21.     nondeterm color(string).
  22.    
  23.     % предикат для задания ребер от одной вершины к другой (Внимание, ребра однонаправленные)
  24.     nondeterm edge(string,string).
  25.    
  26.     % для упрощения будем рассметривать неориент графы, поэтому вместо edge будем использовать connected
  27.     % connected(A, B) - истина, если А и В соединены ребром, неважжно A->B  или B->A
  28.     nondeterm connected(string,string).
  29.     % итоговый предикат, запускающий решение
  30.     colorize.
  31.    
  32.     % предикат для проверки подбираемого решения, подробнее разберем ниже
  33.     nondeterm check_solution(string,string,string,string,string,string,string,string).
  34.    
  35.     % предикат для красивого вывода просто
  36.     nondeterm output.
  37. CLAUSES
  38.     % если то, что мы ищем (X) - голова списка, то это правда, что X содержится в списке
  39.     contains([X|Xs],X):-!.
  40.     % если же не голова, то возможно он где-то в хвосте - запускаем рекурсивно
  41.     contains([X|Xs],Y):-
  42.         contains(Xs,Y).
  43.  
  44.     % объявим возможные цвета
  45.     color(blue).
  46.     color(red).
  47.     color(green).
  48.     color(black).
  49.     color(white).
  50.  
  51.     % вершины
  52.     vertex(a).
  53.     vertex(b).
  54.     vertex(c).
  55.     vertex(d).
  56.    
  57.     % ребра
  58.     edge(a,b).
  59.     edge(b,c).
  60.     edge(b,d).
  61.     edge(c,d).
  62.    
  63.     % две вершины x y соединены, если есть ребро y->x или x->y
  64.     connected(X,Y):-edge(X,Y);edge(Y,X).
  65.    
  66.     % предикат для проверки решения
  67.     % рассматриваем граф из 4 вершин
  68.     % он принимает 8 аргументов, 4 вершины и 4 соответсвующих цвета вершин
  69.     check_solution(A,ACol,B,BCol,C,CCol,D,DCol):-
  70.         % с помощью connects_cols получаем цвета смежных вершин с каждой из четырех
  71.         connects_cols(A,ANsCols),
  72.         connects_cols(B,BNsCols),
  73.         connects_cols(C,CNsCols),
  74.         connects_cols(D,DNsCols),
  75.        
  76.         % затем указываем, что цвет каждой вершины не должен содержаться в цветах смежных с ней вершин
  77.         % - это как бы раскраска графа
  78.         not(contains(ANsCols,ACol)),
  79.         not(contains(BNsCols,BCol)),
  80.         not(contains(CNsCols,CCol)),
  81.         not(contains(DNsCols,DCol))
  82.         .
  83.    
  84.     % получаем цвета всех смежных с данной вершиной
  85.     connects_cols(V,ConnCols):-
  86.         % findall - это встроенный предикат, он позволяет получить список чего либо удовлетворяющего какому либо условию
  87.         % найдем все смежные вершины с V:
  88.         findall(X,connected(X,V),Cs), % в инете нашел пример и сделал по аналогии
  89.         % все смежные вершины запишуться в переменную Cs, то есть список смежных вершин
  90.         % затем преобразуем эти названия вершин в их цвета с помощью предиката vertsToCols
  91.         % список соответсвующих цветов получаем в переменной ConnCols - втором аргументее vertsToCols в итоге получается, что второй
  92.         % аргумент connects_cols - ConnCols равеен списку цветов смежныых с V вершин
  93.         vertsToCols(Cs,ConnCols),!.
  94.    
  95.     % преобразуем список вершин в список их цветов
  96.     vertsToCols([],[]).
  97.     vertsToCols([V|VS],[C|CS]):-
  98.         % отщепляем головы с обоих и должно быть, что соответсвующая голова V должна иметь цвет C,
  99.         % задаем это условие с помощью выражения vcolor(V,C)
  100.         vcolor(V,C),vertsToCols(VS,CS). % и рекурсивно вызываем от хвостов
  101.        
  102.     % итоговый
  103.     colorize:-
  104.         % для удобства запишем вершины в переменные (хотя на самом деле можно обойтись и без них)
  105.         A=a,B=b,C=c,D=d,
  106.         color(C1),color(C2),color(C3),color(C4), % тут и происходит перебор
  107.        
  108.         retractall(vcolor(_,_)), % очищаем БД, чтобы отсеять результат предыдущего перебора
  109.        
  110.         % assert присваивает/добавляет факт в бд - это встроенный предикат
  111.         % пусть А имеет цвет С1 и тд
  112.         assert(vcolor(A,C1)),assert(vcolor(B,C2)),assert(vcolor(C,C3)),assert(vcolor(D,C4)),
  113.        
  114.         % проверим решение с помощью вышеописанного предиката
  115.         check_solution(A,C1,B,C2,C,C3,D,C4),
  116.        
  117.         % если проверка пройдена - выведем решение
  118.         output,
  119.         !.
  120.     output:-
  121.         % получим список всех цветов
  122.         findall(V,vcolor(X,V),Cs),
  123.         % получаем список всех вершин
  124.         findall(X,vcolor(X,V),Vs),
  125.        
  126.         %пишем в консоль найденное решение
  127.         write("Vertexes:\t\t"),write(Vs),nl,
  128.         write("Colors:\t\t"),write(Cs),nl,nl.
  129. GOAL
  130.     colorize.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement