SWI Prolog задача про фигуры и их цвета относительно расположения

Узнай цену своей работы

Формулировка задачи:

Доброе время суток! Задача: На столе лежат в четыре ряда фигуры: треугольник, ромб, круг и квадрат. Цвета этих фигур - зеленый, желтый, синий, красный. Фигура красного цвета лежит между зеленой и синей (возможно, не рядом), справа от желтой фигуры лежит ромб, круг лежит правее треугольника и ромба, причем треугольник лежит не с краю и, наконец, фигура синего цвета не лежит рядом с фигурой желтого цвета. Определить, какого цвета круг. Наработка:
Логика наработки не верна, т.к. зависимость цвета от расположения фигуры не учтена. Не могу найти логически похожую задачу, может кто подскажет?

Решение задачи: «SWI Prolog задача про фигуры и их цвета относительно расположения»

textual
Листинг программы
/*
На столе лежат в четыре ряда фигуры:
  треугольник, ромб, круг и квадрат.
Цвета этих фигур -
  зеленый, желтый, синий, красный.
Фигура красного цвета лежит между зеленой и синей (возможно, не рядом),
справа от желтой фигуры лежит ромб,
круг лежит правее треугольника и ромба,
причем треугольник лежит не с краю и, наконец,
фигура синего цвета не лежит рядом с фигурой желтого цвета.
Определить, какого цвета круг.
*/
 
f(['треугольник', 'ромб', 'круг', 'квадрат']).
c(['зеленый', 'желтый', 'синий', 'красный']).
s([1, 2, 3, 4, 5]).
 
fc(FC) :-
    f(F), c(C), s(S),
    permutation1(F, F1),
    permutation1(C, C1),
    by_pairs(F1, C1, FC),
    check_rules(S, FC).
 
by_pairs([], [], []).
by_pairs([H1 | T1], [H2 | T2], [H1-H2 | R]) :-
    by_pairs(T1, T2, R).
 
check_rules([], _).
check_rules([H | T], FC) :-
    r(H, FC),
    check_rules(T, FC).
 
% Фигура красного цвета лежит между зеленой и синей (возможно, не рядом),
r(1, FC) :-
    select1(C1, [_-'зеленый', _-'синий'], [C2]),
    append1(_, [ C1 | R1], FC),
    append1(_, [_-'красный' | R2], R1),
    member1(C2, R2).
% справа от желтой фигуры лежит ромб,
r(2, FC) :-
   append1(_, [_-'желтый', 'ромб'-_ | _], FC).
% круг лежит правее треугольника и ромба,
r(3, FC) :-
   select1(F1, ['треугольник'-_, 'ромб'-_], [F2]),
   append1(_, [F1, F2, 'круг'-_ | _], FC).
% причем треугольник лежит не с краю и, наконец,
r(4, FC) :-
    \+ FC = ['треугольник'-_ | _],
    \+ append1(_, ['треугольник'-_], FC).
% фигура синего цвета не лежит рядом с фигурой желтого цвета.
r(5, FC) :-
   \+ append1(_, [_-'желтый', _-'синий' | _], FC),
   \+ append1(_, [ _-'синий', _-'желтый' | _], FC).
 
permutation1([], []).
permutation1(List, [First | Perm]) :-
        select1(First, List, Rest),
        permutation1(Rest, Perm).
 
select1(Elem, [Elem | Tail], Tail).
select1(Elem, [Head | Tail], [Head | Rest]) :-
    select1(Elem, Tail, Rest).
 
member1(Elem, [Elem | _]).
member1(Elem, [_ | Tail]):-
    member1(Elem, Tail).
 
% если левый список пуст, то итоговый список совпадает с правым списком
append1([], RightList, RightList).
% иначе, взять голову из левого списка и перенести в голову итогового списка,
append1([LeftHead|LeftTeil], RightList, [LeftHead|RightPart]) :-
    % продолжить для хвоста левого списка
    append1(LeftTeil, RightList, RightPart).

Оцени полезность:

8   голосов , оценка 4.25 из 5