Решение простой геометрической головоломки в CLPQ/R (Пролог)

Рассмотрим следующий квадрат:

Вам дается три ограничения:

  1. Все прямоугольники (A, B, C, D и E) имеют одинаковую площадь;
  2. Их геометрическое расположение представляет собой квадрат; а также
  3. Высота A равна 2.

Теперь я знаю, что это очень просто решить вручную, но я подумал, что это будет очень хороший пример, демонстрирующий возможности CLP(Q/R) с Prolog:


СПОЙЛЕР ПРЕДУПРЕЖДЕНИЕ: если вы хотите сначала решить головоломку самостоятельно, не продолжайте читать это, так как есть ограничения, которые выдадут решение.


Во всяком случае, вот моя попытка определить (с учетом избыточных ограничений) эту головоломку с помощью CLP(Q/R):

:- use_module(library(clpr)).

solve(Eh) :-
  A = B, B = C, C = D, D = E,

  { A  >= 1, B  >= 1, C  >= 1, D  >= 1, E  >= 1,
    Aw >= 1, Bw >= 1, Cw >= 1, Dw >= 1, Ew >= 1 },
  
  { Ah = 2 },
  
  { A = Ah * Aw,
    B = Bh * Bw,
    C = Ch * Cw,
    D = Dh * Dw,
    E = Eh * Ew },

  { (Bw + Cw) = Aw,
     Dw = Cw,
    (Ah + Bh) = Eh,
    (Ch + Dh) = Bh,
    (Aw + Ew) = Eh },

  minimize(Eh).

Что при запросе:

?- solve(Eh).
false.

...огорчает меня. Такой красивый пример для решателя ограничений... Кто-нибудь хочет избавиться от моей печали?


Приложение: я использовал Mathematica иFindMinimumфункция для проверки моих ограничений. Кажется, это работает:

domain = a >= 1 && b >= 1 && c >= 1 && d >= 1 && e >= 1 && ah == 2.0 && a == b == c == d == e && aw >= 1 && bw >= 1 && cw >= 1 && dw >= 1 && ew >= 1
rectangles = (a == ah*aw && b == bh*bw && c == ch*cw && d == dh*dw && e == eh*ew)

FindMinimum[{eh, 
  domain && rectangles &&
  ((bw + cw ) == aw && dw == cw && (ah + bh) == eh && (ch + dh) == bh && (aw + ew) == eh)}, 
  {a, b, c, d, e, ah, aw, bh, bw, ch, cw, dh, dw, eh, ew}]

Ответы:

{8., {a -> 12.8, b -> 12.8, c -> 12.8, d -> 12.8, e -> 12.8, 
      ah -> 2., aw -> 6.4, bh -> 6., bw -> 2.13333, ch -> 3., 
      cw -> 4.26667, dh -> 3., dw -> 4.26667, 
      eh -> 8., ew -> 1.6}}

1 ответ

Решение

В CLP есть старая / новая запись clpBNR. Вы можете установить его в последней версии SWI-Prolog.

Я думаю, что потребуется сгруппировать уравнения в один {}.

?- pack_install(clpBNR).

:- use_module(library(clpBNR)).

solve_(Eh) :-
  Vs = [A,B,C,D,E, Aw,Bw,Cw,Dw,Ew, Ah,Bh,Ch,Dh,Eh],
  Vs::real(1,100),

  { Ah == 2,

    A is Ah * Aw,
    B is Bh * Bw,
    C is Ch * Cw,
    D is Dh * Dw,
    E is Eh * Ew,

    A == B,
    B == C,
    C == D,
    D == E,

    (Bw + Cw) == Aw,
     Dw == Cw,
    (Ah + Bh) == Eh,
    (Ch + Dh) == Bh,
    (Aw + Ew) == Eh
  },

  solve(Vs).

?- solve_(Eh).
::(Eh, ...( 8.000000)) .
Другие вопросы по тегам