Jobshop#

  • Backend: ClingoDLBackend

This example is a simple version of the job-shop scheduling problem which uses clingodl.

Usage#

$ clinguin client-server --domain-files jobshop/encoding.lp  jobshop/instance.lp --ui-files jobshop/ui.lp  --backend ClingoDLBackend

Domain Files#

instance.lp#
#const n=100.

executionTime(1,1,10).
executionTime(1,2,20).
executionTime(1,3,5).
executionTime(1,4,10).
executionTime(2,1,9).
executionTime(2,2,15).
executionTime(2,3,20).
executionTime(2,4,3).
executionTime(3,1,2).
executionTime(3,2,10).
executionTime(3,3,2).
executionTime(3,4,2).
assign(1,1,3).
assign(1,2,1).
assign(1,3,4).
assign(1,4,2).
assign(2,1,4).
assign(2,2,1).
assign(2,3,2).
assign(2,4,3).
assign(3,1,1).
assign(3,2,2).
assign(3,3,3).
assign(3,4,4).
bound(n).
encoding.lp#
task(T):-executionTime(T,_,_).
subtask((T,ST)):-executionTime(T,ST,_).
machine(M):-assign(_,_,M).

% decide which operation first
seq((T,ST1),(T,ST2),Time1) :- assign(T,ST1,M1), assign(T,ST2,M2), ST1<ST2, executionTime(T,ST1,Time1), executionTime(T,ST2,Time2).
seq((T,ST2),(T,ST1),Time2) :- assign(T,ST1,M1), assign(T,ST2,M2), ST1<ST2, executionTime(T,ST1,Time1), executionTime(T,ST2,Time2), not seq((T,ST1),(T,ST2),Time1).

% decide which task first on machine
{seq((T1,ST1),(T2,ST2),Time1)} :- assign(T1,ST1,M), assign(T2,ST2,M), T1<T2, executionTime(T1,ST1,Time1), executionTime(T2,ST2,Time2).
seq((T2,ST2),(T1,ST1),Time2) :- assign(T1,ST1,M), assign(T2,ST2,M), T1<T2, executionTime(T1,ST1,Time1), executionTime(T2,ST2,Time2), not seq((T1,ST1),(T2,ST2),Time1).

&diff{T1-T2}<= -Time:-seq(T1,T2,Time).

&diff{0-T} <= 0 :- subtask(T), bound(B).
&diff{T-0} <= B :- subtask(T), bound(B).

UI Files#

ui.lp#
pos(M,(T1,ST1),1) :- assign(T1,ST1,M), #false: assign(T2,ST2,M), seq((T2,ST2),(T1,ST1),_).
pos(M,(T2,ST2),X+1) :- assign(T1,ST1,M),  assign(T2,ST2,M), seq((T1,ST1),(T2,ST2),_),
        pos(M,(T1,ST1),X),
        #false :  assign(T3,ST3,M), seq((T1,ST1),(T3,ST3),_), seq((T3,ST3),(T2,ST2),_).

color(1,"bg-primary").
color(2,"bg-success").
color(3,"bg-warning").


elem(window, window, root).
attr(window, class, ("column-reverse";"justify-content-between")).

    %%%%%%%%%%%%%%%%%%%%%%%%
    % Machine containers
    %%%%%%%%%%%%%%%%%%%%%%%%
    elem(c(M), container, window):- machine(M).
    attr(c(M), class, ("border";"border-dark";"bg-secondary";"rounded";"bg-opacity-25";"m-1";"p-1")):- machine(M).
    attr(c(M), flex_direction, column):- machine(M).

        %%%%%%%%%%%%%%%%%%%%%%%%
        % Title
        %%%%%%%%%%%%%%%%%%%%%%%%
        elem(ctitle(M), label, c(M)):- machine(M).
        attr(ctitle(M), label, @concat( "Machine ", M)):- machine(M).
        attr(ctitle(M), class, "fw-bold"):- machine(M).
        attr(ctitle(M), order, 1):- machine(M).

        %%%%%%%%%%%%%%%%%%%%%%%%
        % Tasks per machine
        %%%%%%%%%%%%%%%%%%%%%%%%
        elem(ctasks(M), container, c(M)):- machine(M).
        attr(ctasks(M), order, 2):- machine(M).
        attr(ctasks(M), flex_direction, row):- machine(M).

            task_not_fixed((T,ST)):-  assign(T,ST,M), assign(T2,ST2,M), seq((T2,ST2),(T,ST),_), _any(seq((T,ST),(T2,ST2),_)).
            task_not_fixed((T,ST)):-  assign(T,ST,M), assign(T2,ST2,M), seq((T,ST),(T2,ST2),_), _any(seq((T2,ST2),(T,ST),_)).

            %%%%%%%%%%%%%%%%%%%%%%%%
            % Task
            %%%%%%%%%%%%%%%%%%%%%%%%
            elem(tc(T,ST), container, ctasks(M)):- assign(T,ST,M).
            attr(tc(T,ST), class, C):- assign(T,ST,M), color(T,C).
            attr(tc(T,ST), class, ("bg-opacity-50";"m-1";"justify-content-between";"align-items-start";"p-1")):- assign(T,ST,M).
            attr(tc(T,ST), order, X+1):- assign(T,ST,M), pos(M,(T,ST),X).
            attr(tc(T,ST), class, "opacity-50"):- assign(T,ST,M), task_not_fixed((T,ST)).
            attr(tc(T,ST), width, Time*25):- executionTime(T,ST,Time).
            attr(tc(T,ST), flex_direction, column):- executionTime(T,ST,Time).
            attr(tc(T,ST), class, ("border";"border-dark";"border-2")):- _clinguin_assume(seq((T,ST),_,_),true).

                %%%%%%%%%%%%%%%%%%%%%%%%
                % Time
                %%%%%%%%%%%%%%%%%%%%%%%%
                elem(tctime(T,ST), label, tc(T,ST)):- _clinguin_assign((T,ST),Start).
                attr(tctime(T,ST), label, @concat("@",Start,"-",Start+ET)):- _clinguin_assign((T,ST),Start), executionTime(T,ST,ET).
                attr(tctime(T,ST), class, "fw-light"):- _clinguin_assign((T,ST),Start).
                attr(tctime(T,ST), fontSize, "8px"):- _clinguin_assign((T,ST),Start).

                %%%%%%%%%%%%%%%%%%%%%%%%
                % Label
                %%%%%%%%%%%%%%%%%%%%%%%%
                elem(tctitle(T,ST), label, tc(T,ST)):- assign(T,ST,M).
                attr(tctitle(T,ST), label, (T,ST)):- assign(T,ST,M).
                attr(tctitle(T,ST), class, "fw-bold"):- assign(T,ST,M).

                %%%%%%%%%%%%%%%%%%%%%%%%
                % Button
                %%%%%%%%%%%%%%%%%%%%%%%%
                elem(tcbtn(T,ST), button, tc(T,ST)):- assign(T,ST,M).
                attr(tcbtn(T,ST), class, ("btn-info"; "btn-sm")):- assign(T,ST,M).
                attr(tcbtn(T,ST), icon, "fa-left-long"):- assign(T,ST,M), task_not_fixed((T,ST)).
                attr(tcbtn(T,ST), icon, "fa-ban"):- assign(T,ST,M), not task_not_fixed((T,ST)), _clinguin_assume(seq((T,ST),_,_),true).
                attr(tcbtn(T,ST), class, "disabled"):- assign(T,ST,M), not task_not_fixed((T,ST)), not _clinguin_assume(seq((T,ST),_,_),true).
                when(tcbtn(T,ST), click, call, add_assumption(seq((T,ST),(T2,ST2),Time),true)):- task_not_fixed((T,ST)), assign(T,ST,M), assign(T2,ST2,M), executionTime(T,ST,Time), (T,ST)!=(T2,ST2), _any(seq((T,ST),(T2,ST2),_)).
                when(tcbtn(T,ST), click, call, remove_assumption_signature((seq((T,ST),any,any)))):- _clinguin_assume(seq((T,ST),_,_),true), assign(T,ST,M).


%%%%%%%%%%%%%%%%%%%%%%%%
% Menu bar
%%%%%%%%%%%%%%%%%%%%%%%%
elem(menu_bar, menu_bar, window).
attr(menu_bar, title, "Job Shop").
attr(menu_bar, icon, "fa-chart-gantt").

    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, callback, next_solution).

    elem(menu_bar_clear, button, menu_bar).
    attr(menu_bar_clear, label, "Clear").
    attr(menu_bar_clear, icon, "fa-trash").
    attr(menu_bar_clear, class, ("btn-outline-danger";"border-0")).
    when(menu_bar_clear, click, callback, clear_assumptions).

    elem(menu_bar_select, button, menu_bar).
    attr(menu_bar_select, label, "Select solution").
    attr(menu_bar_select, icon, "fa-hand-pointer").
    when(menu_bar_select, click, callback, select).