Cats and dogs#
Backend:
ExplanationBackend
This example was used in the paper for clinguin in ICLP 2024. The aim is to place people in tables so that no cat-people are sitting with dog-people.
Usage#
$ clinguin client-server --domain-files catdog/{instance.lp,encoding.lp} --ui-files catdog/{ui-tables.lp,ui-menu.lp,ui-people.lp,ui-explain.lp,ui-explain-msg.lp} --backend ExplanationBackend --assumption-signature cons,2
Domain Files#
person("Susana",cat). person("Alexander",cat). person("Torsten",dog).
seat((1,1..2)). seat((2,1..3)).
{assign(P,S):seat(S)}:- person(P,_).
:- person(P,_), #count{S:assign(P, S)}!=1, cons(exacly_one, _).
:- assign(P,S), assign(P',S), P'>P, cons(only_one, _).
:- assign(P,(T,_)), assign(P',(T,_)), person(P,cat), person(P',dog),
cons(different_type, _).
cons(exacly_one, "All people need exactly one seat").
cons(only_one, "Two people can not be seated on the same seat").
cons(different_type, "All people on a table must prefer the same pet").
UI Files#
elem(w, window, root).
attr(w, flex_direction, row).
elem(tables, container, w).
elem(table(T), container, tables):- seat((T,_)).
attr(table(T), order, T):- seat((T,_)).
attr(table(T), width, 200):- seat((T,_)).
attr(table(T), class, ("bg-primary";"bg-opacity-25";"rounded";
"d-flex";"flex-column";"align-items-start";
"p-2";"m-2"
)):- seat((T,_)).
elem(table_label(T), label, table(T)):- seat((T,_)).
attr(table_label(T), order, 1):- seat((T,_)).
attr(table_label(T), label, @concat("","Table",T)):- seat((T,_)).
elem(seat_dd((T,C)), dropdown_menu, table(T)):- seat((T,C)).
attr(seat_dd((T,C)), order, C+1):- seat((T,C)).
attr(seat_dd(S), class, ("btn-sm";"btn-primary";"m-2")):- seat(S).
attr(seat_dd(S), selected, P):- _clinguin_assume(assign(P,S),true).
elem(seat_ddi(S,P), dropdown_menu_item, seat_dd(S)):-_any(assign(P,S)).
attr(seat_ddi(S,P), label, P):- _any(assign(P,S)).
when(seat_ddi(S,P), click, call, add_assumption(assign(P,S),true)):-
_any(assign(P,S)).
%------------------------------
% Extension from the paper
% -----------------------------
elem(seat_ddi(S,remove), dropdown_menu_item, seat_dd(S)):- seat(S).
attr(seat_ddi(S,remove), label, "-"):- seat(S).
when(seat_ddi(S,remove), click, call, remove_assumption_signature(assign(any,(S)))):- seat(S).
elem(menu_bar, menu_bar, w).
attr(menu_bar, title, "Table placement").
attr(menu_bar, icon, "fa-utensils").
elem(menu_bar_next, button, menu_bar).
attr(menu_bar_next, label, "Next").
attr(menu_bar_next, icon, "fa-forward-step").
when(menu_bar_next, click, call, next_solution).
attr(seat_dd(S), selected, P):- assign(P,S), _clinguin_browsing.
attr(seat_dd(S), class, "text-success"):- _clinguin_browsing,
assign(P,S), not _all(assign(P,S)).
attr(seat_dd(S), class, "opacity-75"):- _all(assign(P,S)),
not _clinguin_assume(assign(P,S),true).
%------------------------------
% Extension from the paper
% -----------------------------
% Download action for instance (We can remove it and just comment that can be used)
elem(menu_bar_download, button, menu_bar).
attr(menu_bar_download, label, "Download instance").
attr(menu_bar_download, icon, "fa-download").
when(menu_bar_download, click, call, (download("#show person/2.","catdog_instance.lp"))).
% Download action for solution and multiple actions for call
elem(menu_bar_download_solution, button, menu_bar).
attr(menu_bar_download_solution, label, "Download solution").
attr(menu_bar_download_solution, icon, "fa-download").
when(menu_bar_download_solution, click, call, download("#show assign/2.","catdog_solution.lp")).
elem(people, container, w).
elem(person(P), button, people):- person(P,_).
attr(person(P), label, P):- person(P,_).
attr(person(P), class, ("disabled";"m-2";"btn-sm")):- person(P,_).
attr(person(P), class, ("btn-outline-secondary")):- person(P,cat).
attr(person(P), class, ("btn-outline-warning")):- person(P,dog).
attr(person(P), icon, @concat("","fa-",O)):- person(P,O).
elem(add_person, button, people).
attr(add_person, label, "Add person").
attr(add_person, icon, "fa-user-plus").
attr(add_person, class, ("btn-info";"m-2")).
when(add_person, click, update, (add_modal, visibility, shown)).
elem(add_modal, modal, w).
attr(add_modal, title, "Add person").
elem(modal_content, container, add_modal).
attr(modal_content, class, ("d-flex";"flex-column")).
elem(name_tf, textfield, modal_content).
attr(name_tf, placeholder, "Enter the name").
attr(name_tf, order, 1).
attr(name_tf, width, 250).
when(name_tf, input, context, (name, _value)).
elem(btns_container, container, modal_content).
attr(btns_container, class, ("d-flex";"flex-row";"justify-content-end")).
attr(btns_container, order, 2).
pet(cat;dog).
elem(add_btn(O), button, btns_container):- pet(O).
attr(add_btn(O), label, "Add"):- pet(O).
attr(add_btn(cat), class, ("m-1";"btn-secondary";"ml-auto")):- pet(O).
attr(add_btn(dog), class, ("m-1";"btn-warning";"ml-auto")):- pet(O).
attr(add_btn(O), icon, @concat("","fa-",O)):- pet(O).
when(add_btn(O), click, context, (pet, O)):- pet(O).
when(add_btn(O), click, call,
add_atom(person(_context_value(name,str), _context_value(pet)))):- pet(O).
elem(seat_ddi(S,P), dropdown_menu_item, seat_dd(S)):-
not _any(assign(P,S)), person(P,_), seat(S).
attr(seat_ddi(S,P), label, P):-
not _any(assign(P,S)), person(P,_), seat(S).
when(seat_ddi(S,P), click, call, add_assumption(assign(P,S),true)):-
not _any(assign(P,S)), person(P,_), seat(S).
attr(seat_ddi(S,P), class, "text-danger"):-
not _any(assign(P,S)), person(P,_), seat(S).
attr(seat_dd(S), class, ("text-danger")):- _clinguin_mus(assign(P,S)).
elem(message_unsat(N), message, w):-_clinguin_mus(cons(N,M)).
attr(message_unsat(N), title, "Explanation"):-_clinguin_mus(cons(N,M)).
attr(message_unsat(N), message, M):-_clinguin_mus(cons(N,M)).
attr(message_unsat(N), type, error):-_clinguin_mus(cons(N,M)).