\chapter{Richiami al codice sviluppato nel Modello a Slot}\label{bookEqModelloASlot}

Questa sezione comprende una raccolta di tutte le equazioni definite all'interno del software per descrivere il modello come un problema di programmazione lineare trattabile da CPLEX.

\begin{itemize}
\item Gli slot devono essere assegnati in fasce orarie e giorni validi da \eqref{eqDominio}:
\begin{lstlisting}
# for the day
self.X_d = self.model.integer_var_list(self.AUX.get_nSlotId(), 0, self.AUX.get_NUM_DAY()-1, "X_d")
# for the hour
self.X_h = self.model.integer_var_list(self.AUX.get_nSlotId(), 0, self.AUX.NUM_SLOT_PER_DAY-1, "X_h")

# serve settare almeno un vincolo per ogni variabile del modello, altrimenti non viene modellata
eqs.append(self.X_h[slotId] >= 0) 
    
if self.AUX.pianoAllocazione[slotId].numSlot > 1:
    # se lo slot è di un solo blocco non serve aggiungere nessun constraint
    eqs.append(self.X_h[slotId] <= self.AUX.NUM_SLOT_PER_DAY - self.AUX.pianoAllocazione[slotId].numSlot)
\end{lstlisting}

\item Al Sabato sono disponibili meno fasce orarie da \eqref{eqDominioSabato}:
\begin{lstlisting}
# il sabato ho meno slot allocabili
eqs.append(if_then(self.X_d[slotId] == self.AUX.get_NUM_DAY()-1, 
   self.X_h[slotId]+self.AUX.pianoAllocazione[slotId].numSlot <= self.PARAM.nSlotSabato))
\end{lstlisting}

\item Slot consecutivi come descritto in \eqref{eqSlotSameInsSameDocConsec}
\begin{lstlisting}
for slotId_i in self.AUX.list_slotInInsegnamento[idInsegnamento]:
    for slotId_j in self.AUX.list_slotInInsegnamento[idInsegnamento]:
        if slotId_i > slotId_j:
            # se gli Slot non sono di tipo EL
            if self.AUX.pianoAllocazione[slotId_i].tipoLezione == TipoLezione.EsercitazioneLaboratorio or self.AUX.pianoAllocazione[slotId_j].tipoLezione == TipoLezione.EsercitazioneLaboratorio:
                continue
                        
            # se non c'è nessun Docente in comune tra i 2 slot (sebbene i due Slot appartengano allo stesso Insegnamento) i due Slot
            # non dovranno essere sovrapposti (vedi slotInsegnamentoNellaStessaGiornataNonSovrapposti()), ma non è necessario
            # che siano consecutivi
            intersez:bool = False
            for doc_i in self.AUX.list_docentiInSlot[slotId_i]:
                if doc_i in self.AUX.list_docentiInSlot[slotId_j]:
                    intersez = True
            if not intersez: 
                continue
                        
            eq = if_then(self.X_d[slotId_i] == self.X_d[slotId_j],
                logical_or(self.X_h[slotId_i] == self.X_h[slotId_j] + self.AUX.pianoAllocazione[slotId_j].numSlot,
                self.X_h[slotId_j] == self.X_h[slotId_i] + self.AUX.pianoAllocazione[slotId_i].numSlot))
\end{lstlisting}

\item Docente allocato in un solo slot orario alla volta da \eqref{eqDocUnSoloSlotAllaVolta}:
\begin{lstlisting}
for slotId_i in self.AUX.list_slotInDocente[docId]:
    for slotId_j in self.AUX.list_slotInDocente[docId]:
        # se i due Slot appartengono allo stesso docente -> non possono essere allocati contemporaneamente
                    
        # se i due Slot si riferiscono entrambi ad Insegnamenti sovrapponibili E APPARTENGONO ad INSEGNAMENTI DIFFERENTI
        if docId in self.map_docentiConInsegnamentiSovrapponibili.keys():
            if self.AUX.pianoAllocazione[slotId_i].idInsegnamento != self.AUX.pianoAllocazione[slotId_j].idInsegnamento:
                            
                ID_INC_i:int = int(self.AUX.list_Insegnamenti[self.AUX.pianoAllocazione[slotId_i].idInsegnamento].ID_INC)
                ID_INC_j:int = int(self.AUX.list_Insegnamenti[self.AUX.pianoAllocazione[slotId_j].idInsegnamento].ID_INC)
                            
                if ID_INC_i in self.map_docentiConInsegnamentiSovrapponibili[docId] and ID_INC_j in self.map_docentiConInsegnamentiSovrapponibili[docId]:
                    continue
                    
        if slotId_j > slotId_i: # as matrice triangolare (gli slotId sono ordinati)
            eq = if_then(X_d[slotId_i] == X_d[slotId_j], 
                logical_or(X_h[slotId_i] >= X_h[slotId_j] + self.AUX.pianoAllocazione[slotId_j].numSlot,
                X_h[slotId_j] >= X_h[slotId_i] + self.AUX.pianoAllocazione[slotId_i].numSlot))
\end{lstlisting}

\item L'ultimo slot orario di un giorno ed il primo del successivo non possono essere allocati per lo stesso Insegnamento come da \eqref{eqSlotInsGiornoDopoNonSubito}:
\begin{lstlisting}
for slotId_i in self.AUX.list_slotInInsegnamento[idInsegnamento]:
    for slotId_j in self.AUX.list_slotInInsegnamento[idInsegnamento]:
                    
        if self.AUX.pianoAllocazione[slotId_i].tipoLezione == TipoLezione.EsercitazioneLaboratorio or self.AUX.pianoAllocazione[slotId_j].tipoLezione == TipoLezione.EsercitazioneLaboratorio:
            continue
                    
        if self.AUX.pianoAllocazione[slotId_i].squadra != Squadra.NoSquadra or self.AUX.pianoAllocazione[slotId_j].squadra != Squadra.NoSquadra:
            continue
                    
        if slotId_i > slotId_j:                        
                        
            eq1 = if_then(
                logical_and(self.X_d[slotId_i]+1 == self.X_d[slotId_j],
                self.X_h[slotId_j]+self.AUX.pianoAllocazione[slotId_j].numSlot == 7),
                self.X_h[slotId_i] > 0)
                    
            eq2 = if_then(
                logical_and(self.X_d[slotId_j]+1 == self.X_d[slotId_i],
                self.X_h[slotId_i]+self.AUX.pianoAllocazione[slotId_i].numSlot == 7),
                self.X_h[slotId_j] > 0)
\end{lstlisting}

\item Slot di uno stesso Insegnamento non sovrapposti salvo casi particoli come specificato nell'equazione \eqref{eqSlotInsNonSovrapposti}
\begin{lstlisting}
for slotId_i in self.AUX.list_slotInInsegnamento[idInsegnamento]:
    for slotId_j in self.AUX.list_slotInInsegnamento[idInsegnamento]:
        if slotId_i > slotId_j:                        
            # se i due Slot hanno Docenti in comune => sono sicuramente consecutivi da self.slotInsegnamentoNellaStessaGiornataConsecutivi()
            isIntersezioneDocenti:bool = False
            for doc_i in self.AUX.list_docentiInSlot[slotId_i]:
                if doc_i in self.AUX.list_docentiInSlot[slotId_j]:
                    isIntersezioneDocenti = True
                        
            # se anche solo uno degli Slot non è a squadre => non posso allocare in parallelo
            isSquadre:bool = (self.AUX.pianoAllocazione[slotId_i].squadra != Squadra.NoSquadra and self.AUX.pianoAllocazione[slotId_j].squadra != Squadra.NoSquadra)
                        
            # se le squadre sono le stesse => non posso allocare in parallelo
            isSameSquadra:bool = (self.AUX.pianoAllocazione[slotId_i].squadra == self.AUX.pianoAllocazione[slotId_j].squadra)
                        
            # Slot della stessa squadra o che non fanno riferimento a squadre non devono essere consecutivi
            if isSquadre and not isSameSquadra:
                continue
            if not isIntersezioneDocenti:
                eq = if_then(self.X_d[slotId_i] == self.X_d[slotId_j],
                    logical_or(self.X_h[slotId_i] >= self.X_h[slotId_j] + self.AUX.pianoAllocazione[slotId_j].numSlot,
                    self.X_h[slotId_j] >= self.X_h[slotId_i] + self.AUX.pianoAllocazione[slotId_i].numSlot))
\end{lstlisting}

\item Slot scelti di un Insegnamento da \eqref{eqSlotScelti}\footnote{Viene introdotta la possibilità di preallocare anche solo il giorno o la fascia oraria dello Slot.}:
\begin{lstlisting}
if self.AUX.pianoAllocazione[slotId].tipoSlot == TipoSlot.SlotScelto:                
    eqs.append(self.X_d[slotId] == self.AUX.pianoAllocazione[slotId].daySlotAllocato)
    eqs.append(self.X_h[slotId] == self.AUX.pianoAllocazione[slotId].hourSlotAllocato)
elif self.AUX.pianoAllocazione[slotId].tipoSlot == TipoSlot.SlotScelto_fasciaOraria:
    eqs.append(self.X_h[slotId] == self.AUX.pianoAllocazione[slotId].hourSlotAllocato)
elif self.AUX.pianoAllocazione[slotId].tipoSlot == TipoSlot.SlotScelto_giorno:
    eqs.append(self.X_d[slotId] == self.AUX.pianoAllocazione[slotId].daySlotAllocato)
\end{lstlisting}

\item Slot di Insegnamenti appartenenti allo stesso Orientamento non possono sovrapporsi come soft o hard constraint come da \eqref{eqPenalitaInOrientamentoHeader}\footnote{Viene omessa la logica di generazione dei vincoli}:
\begin{lstlisting}
# Hard Constraint
eq = if_then(X_d[rule.slotId_i] == X_d[rule.slotId_j],
        logical_or(X_h[rule.slotId_i] >= X_h[rule.slotId_j] + self.AUX.pianoAllocazione[rule.slotId_j].numSlot,
            X_h[rule.slotId_j] >= X_h[rule.slotId_i] + self.AUX.pianoAllocazione[rule.slotId_i].numSlot))
    
# Soft Constraint
 eq = if_then(
        logical_and(
            logical_and(X_d[rule.slotId_i] == X_d[rule.slotId_j],
                logical_not(X_h[rule.slotId_i] >= X_h[rule.slotId_j] + self.AUX.pianoAllocazione[rule.slotId_j].numSlot)
            ), logical_not(X_h[rule.slotId_j] >= X_h[rule.slotId_i] + self.AUX.pianoAllocazione[rule.slotId_i].numSlot)
    ),
    X_penalties[index] == rule.valPenalita)
\end{lstlisting}

\item Preferenza su quando allocare o non allocare gli Slot di un Insegnamento come in \eqref{eqPreferenzaInsegnamentoHard} e \eqref{eqPreferenzaInsegnamentoSoft}
\begin{lstlisting}
# Hard Constraint -> per indicare indisponibilità Insegnamento
eq = if_then(X_d[rule.slotId] == getIntFromDay(rule.day),
        logical_or( # inizia dopo o finisce prima
             X_h[rule.slotId] > getIntFromFasciaOraria(rule.fasciaOraria), X_h[rule.slotId] + self.AUX.pianoAllocazione[rule.slotId].numSlot <= getIntFromFasciaOraria(rule.fasciaOraria)
        ))
        
# Soft Constraint
# se lo Slot è allocato quel giorno e NON inizia dopo O NON finisce prima
eq = if_then(logical_and( 
        X_d[rule.slotId] == getIntFromDay(rule.day),
            logical_not(logical_or(                                            
                X_h[rule.slotId] > getIntFromFasciaOraria(rule.fasciaOraria),
                X_h[rule.slotId] + self.AUX.pianoAllocazione[rule.slotId].numSlot <= getIntFromFasciaOraria(rule.fasciaOraria)
            ))),
            X_penalties[index] == getIntFromLV_Penalties(rule.penalita, TipoPenalty.Orientamento))
eq1 = if_then(logical_not(logical_and( 
        X_d[rule.slotId] == getIntFromDay(rule.day),
            logical_not(logical_or(                                            
                X_h[rule.slotId] > getIntFromFasciaOraria(rule.fasciaOraria),
                X_h[rule.slotId] + self.AUX.pianoAllocazione[rule.slotId].numSlot <= getIntFromFasciaOraria(rule.fasciaOraria)
            )))),
            X_penalties[index] == 0)
\end{lstlisting}

\item Allineamento X\_Orient come specificato da \eqref{eqAddX_Orient}\footnote{\textit{self.helper_getOffsetOrient(..) ritorna il corretto pStud associato all'equazione corrente.}}:
\begin{lstlisting}
if self.AUX.list_slotIdInOrientamento_periodoDidattico[orientId][index_slot] in [PeriodoDidattico.PrimoAnno_PrimoSemestre, PeriodoDidattico.PrimoAnno_SecondoSemestre]:
    eq = if_then(logical_and(X_d[slotId] == day, X_h[slotId] == hour), self.X_orient[self.helper_getOffsetOrient(orientId,1)+day*self.AUX.NUM_SLOT_PER_DAY+hour+nSlot_durata] == 1)
\end{lstlisting}

\item Limite di 6 slot orari giornalieri come specificato da \eqref{eqMaxSlotGiornalieri}:
\begin{lstlisting}
eqMax = model.sum(self.X_orient[self.helper_getOffsetOrient(orientId,3)+day*self.AUX.NUM_SLOT_PER_DAY+i] == 1 for i in range(self.AUX.NUM_SLOT_PER_DAY)) <= 6
\end{lstlisting}

\item Limite di 5 slot orari consecutivi come specificato da \eqref{eqMaxSlotGiornalieriConsecutivi}:
\begin{lstlisting}
# se ho 6 slot allocati => il primo e l'ultimo della giornata devono essere entrambi allocati
# per avere l'ora buca non agli estremi della giornata e quindi avere max 5 slot consecutivi 
eqCons = if_then(model.sum(self.X_orient[self.helper_getOffsetOrient(orientId,3)+day*self.AUX.NUM_SLOT_PER_DAY+i] == 1 for i in range(self.AUX.NUM_SLOT_PER_DAY)) == 6,
    logical_and(self.X_orient[self.helper_getOffsetOrient(orientId,3)+day*self.AUX.NUM_SLOT_PER_DAY] == 1,
        self.X_orient[self.helper_getOffsetOrient(orientId,3)+day*self.AUX.NUM_SLOT_PER_DAY+self.AUX.NUM_SLOT_PER_DAY-1] == 1))
\end{lstlisting}

\item Penalità se ci sono 4 slot orari consecutivi come specificato da \eqref{eq4SlotLezioneConsecutivi}\footnote{\textit{rOr(eqs)} è una funzione che mette in or logico tra loro la lista di equazioni passata come parametro.}:
\begin{lstlisting}
listOptEq = list()
for hStart in range(self.AUX.NUM_SLOT_PER_DAY-3):
    eq_if = model.sum(
        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + hStart+i] == 1
            for i in range(4)) == 4
    listOptEq.append(eq_if)

# pseudocode
# eq = if_then(logical_or(listOptEq[0], ...), X_penaltiesStud[pStud] == LV_Penalties.LV_1)
self.listRuleStudente.append(RuleStudente(rOr(listOptEq), LV_Penalties.LV_1, 
    self.helper_getOffsetPenalita(orientId, year, day),
    orientId, year, day, TipoRuleStudente.SlotConsecutivi,
    self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY))
\end{lstlisting}

\item Penalità se c'è un intervallo da due slot orari come specificato da \eqref{eqBucoDa2Slot}:
\begin{lstlisting}
listOptEq = list()
eq_if = logical_and(model.sum(
    self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
       for i in range(buco)) 
    == model.sum(
        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
            for i in range(buco+2))
    , 
        model.sum(
            self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
                for i in range(buco)) 
        != model.sum(
            self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + j] 
                for j in range(buco+3))) 
                        # no self.AUX.NUM_SLOT_PER_DAY perchè altrimenti saprei solo se ho un buco di ALMENO 3 slot
listOptEq.append(eq_if)

# pseudocode
# eq = if_then(logical_or(listOptEq[0], ...), X_penaltiesStud[pStud] == LV_Penalties.LV_1)
self.listRuleStudente.append(RuleStudente(rOr(listOptEq), LV_Penalties.LV_1, 
    nVarSlotConsecutivi + self.helper_getOffsetPenalita(orientId, year, day),
    orientId, year, day, TipoRuleStudente._1BucoOrario,
    self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY))
\end{lstlisting}

\item Penalità se ci sono 2 intervalli lo stesso giorno come specificato da \eqref{eq2BuchiOrario}:
\begin{lstlisting}
for buco1 in range(1,self.AUX.NUM_SLOT_PER_DAY-1-2):
    for buco2 in range(buco1+2, self.AUX.NUM_SLOT_PER_DAY-1):
        eq_if = logical_and(
            logical_and(
                logical_and(
                    model.sum(                                           
                        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
                            for i in range(buco1))
                    == model.sum(
                        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
                            for i in range(buco1+1))
                ,
                    model.sum(
                        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
                            for i in range(buco1))
                    != model.sum(
                        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
                            for i in range(buco2))
                    )
                ,
                    model.sum(
                        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
                            for i in range(buco2))
                    == model.sum(
                        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
                            for i in range(buco2+1))
                    )
                ,
                    model.sum(
                        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
                            for i in range(buco2))
                    !=  model.sum(                                        
                        self.X_orient[self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY + i] 
                            for i in range(self.AUX.NUM_SLOT_PER_DAY))
                    )
        # pseudocode
        # eq = if_then(eq_if, X_penaltiesStud[pStud] == LV_Penalties.LV_6)
        self.listRuleStudente.append(RuleStudente(eq_if, LV_Penalties.LV_6, 
            nVarSlotConsecutivi + nVar1Buco + self.helper_getOffsetPenalita(orientId, year, day),
            orientId, year, day, TipoRuleStudente._2BuchiOrario,
            self.helper_getOffsetOrient(orientId,year)+day*self.AUX.NUM_SLOT_PER_DAY))
\end{lstlisting}

\item Limite disponibilità Locali da \eqref{eqLocali}:
\begin{lstlisting}
 eq1 = model.sum((X_d[slotId] == day)*(X_h[slotId] <= h)*((X_h[slotId]+self.AUX.pianoAllocazione[slotId].numSlot > h)) 
        for slotId in self.listSlot_ACSLAB) <= self.getLimit(day, h, TipoLocale.ACSLAB)
\end{lstlisting}

\item Limite slot orari allocati per un Docente da \eqref{eqMaxSlotGiornalieriDocente}
\begin{lstlisting}
eqs.append(model.sum([(X_d[slotId] == day) * self.AUX.pianoAllocazione[slotId].numSlot 
    for slotId in self.AUX.list_slotInDocente[docId]]) <= self.map_limitHourDocentePerDay[docId])
\end{lstlisting}

\item Distanza minima tra due Slot associati ad un Docente da \eqref{eqDistMinimaHard} e \eqref{eqDistMinimaSoft}:
\begin{lstlisting}
# Hard Constraint
eq = if_then(X_d[rule.slotId_i] == X_d[rule.slotId_j],
    logical_or(
        X_h[rule.slotId_i] >= X_h[rule.slotId_j] + self.AUX.pianoAllocazione[rule.slotId_j].numSlot + rule.dist,
        X_h[rule.slotId_j] >= X_h[rule.slotId_i] + self.AUX.pianoAllocazione[rule.slotId_i].numSlot + rule.dist
    ))

# Soft Constraint
eq = if_then(logical_and(
        X_d[rule.slotId_i] == X_d[rule.slotId_j],
        logical_not(logical_or(
            X_h[rule.slotId_i] >= X_h[rule.slotId_j] + self.AUX.pianoAllocazione[rule.slotId_j].numSlot + rule.dist,
            X_h[rule.slotId_j] >= X_h[rule.slotId_i] + self.AUX.pianoAllocazione[rule.slotId_i].numSlot + rule.dist
        ))
    ),
        X_penaltiesDoc[index] == getIntFromLV_Penalties(rule.penalita, TipoPenalty.Docente)
    )
eq1 = if_then(logical_not(logical_and(
        X_d[rule.slotId_i] == X_d[rule.slotId_j],
        logical_not(logical_or(
            X_h[rule.slotId_i] >= X_h[rule.slotId_j] + self.AUX.pianoAllocazione[rule.slotId_j].numSlot + rule.dist,
            X_h[rule.slotId_j] >= X_h[rule.slotId_i] + self.AUX.pianoAllocazione[rule.slotId_i].numSlot + rule.dist
        ))
    )),
        X_penaltiesDoc[index] == 0
    )
\end{lstlisting}

\item Distanza massima tra due Slot associati ad un Docente da \eqref{eqDistMassimaHard} e \eqref{eqDistMassimaSoft}:
\begin{lstlisting}
# Hard Constraint
eq = if_then(logical_and(
        X_d[rule.slotId_i] == X_d[rule.slotId_j],
        X_h[rule.slotId_i] > X_h[rule.slotId_j]
    ),
        X_h[rule.slotId_i] <= X_h[rule.slotId_j] + self.AUX.pianoAllocazione[rule.slotId_j].numSlot + rule.dist
    )
eq1 = if_then(logical_and(
        X_d[rule.slotId_i] == X_d[rule.slotId_j],
        X_h[rule.slotId_j] > X_h[rule.slotId_i]
    ),
        X_h[rule.slotId_j] <= X_h[rule.slotId_i] + self.AUX.pianoAllocazione[rule.slotId_i].numSlot + rule.dist
    )
    
# Soft Constraint
eq = if_then(logical_and(
    X_d[rule.slotId_i] == X_d[rule.slotId_j],
    logical_or(
        logical_and(
           X_h[rule.slotId_i] > X_h[rule.slotId_j],
           X_h[rule.slotId_i] > X_h[rule.slotId_j] + self.AUX.pianoAllocazione[rule.slotId_j].numSlot + rule.dist
        ), logical_and(
            X_h[rule.slotId_j] > X_h[rule.slotId_i],
            X_h[rule.slotId_j] > X_h[rule.slotId_i] + self.AUX.pianoAllocazione[rule.slotId_i].numSlot + rule.dist
        )
    )),
    X_penaltiesDoc[index] == getIntFromLV_Penalties(rule.penalita, TipoPenalty.Docente))
eq1 = if_then(logical_not(logical_and(
    X_d[rule.slotId_i] == X_d[rule.slotId_j],
    logical_or(
        logical_and(
           X_h[rule.slotId_i] > X_h[rule.slotId_j],
           X_h[rule.slotId_i] > X_h[rule.slotId_j] + self.AUX.pianoAllocazione[rule.slotId_j].numSlot + rule.dist
        ), logical_and(
            X_h[rule.slotId_j] > X_h[rule.slotId_i],
            X_h[rule.slotId_j] > X_h[rule.slotId_i] + self.AUX.pianoAllocazione[rule.slotId_i].numSlot + rule.dist
        )
    ))),
    X_penaltiesDoc[index] == 0)
\end{lstlisting}

\item Slot di Insegnamenti differenti associati allo stesso Docente non dovrebbero essere allocati lo stesso giorno da \eqref{eqSlotStessoGiornoHard} e \eqref{eqSlotStessoGiornoSoft}:
\begin{lstlisting}
# Hard Constraint
eq = X_d[rule.slotId_i] != X_d[rule.slotId_j]

# Soft Constraint
eq = if_then(
    X_d[rule.slotId_i] == X_d[rule.slotId_j],
    X_penaltiesDoc[index] == getIntFromLV_Penalties(rule.penalita, TipoPenalty.Docente)
)
eq1 = if_then(
    X_d[rule.slotId_i] != X_d[rule.slotId_j],
    X_penaltiesDoc[index] == 0
)
\end{lstlisting}

\item Slot s1 almeno un giono dopo un altro Slot s2 da \eqref{eqVincoloAlmenoUnGiornoDopoHard} e \eqref{eqVincoloAlmenoUnGiornoDopoSoft}:
\begin{lstlisting}
# Hard Constraint
eq = X_d[self.slotId_i] > X_d[self.slotId_j]

# Soft Constraint
eq = if_then(X_d[self.slotId_i] > X_d[self.slotId_j],
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
eq1 = if_then(logical_not(X_d[self.slotId_i] > X_d[self.slotId_j]),
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
\end{lstlisting}

\item Slot s1 in un giorno diverso da un altro Slot s2 da \eqref{eqVincoloGiornoDiversoHard} e \eqref{eqVincoloGiornoDiversoSoft}:
\begin{lstlisting}
# Hard Constraint
eq = X_d[self.slotId_i] != X_d[self.slotId_j]

# Soft Constraint
eq = if_then(X_d[self.slotId_i] != X_d[self.slotId_j],
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
eq1 = if_then(logical_not(X_d[self.slotId_i] != X_d[self.slotId_j]),
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
\end{lstlisting}

\item Slot s1 stesso giorno di un altro Slot s2 da \eqref{eqVincoloStessoGiornoHard} e \eqref{eqVincoloStessoGiornoSoft}:
\begin{lstlisting}
# Hard Constraint
eq = X_d[self.slotId_i] == X_d[self.slotId_j]

# Soft Constraint
eq = if_then(X_d[self.slotId_i] == X_d[self.slotId_j],
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
eq1 = if_then(logical_not(X_d[self.slotId_i] == X_d[self.slotId_j]),
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
\end{lstlisting}

\item Slot s1 parallelo ad un altro Slot s2 da \eqref{eqVincoloParalleloHard} e \eqref{eqVincoloParalleloSoft}:
\begin{lstlisting}
# Hard Constraint
eq = logical_and(X_d[self.slotId_i] == X_d[self.slotId_j], X_h[self.slotId_i] == X_h[self.slotId_j])

# Soft Constraint
eq = if_then(logical_and(X_d[self.slotId_i] == X_d[self.slotId_j], X_h[self.slotId_i] == X_h[self.slotId_j]),
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
eq1 = if_then(logical_not(logical_and(X_d[self.slotId_i] == X_d[self.slotId_j], X_h[self.slotId_i] == X_h[self.slotId_j])),
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
\end{lstlisting}

\item Slot s1 subito dopo un altro Slot s2 da \eqref{eqVincoloSubitoDopoHard} e \eqref{eqVincoloSubitoDopoSoft}:
\begin{lstlisting}
# Hard Constraint
eq = logical_and(X_d[self.slotId_i] == X_d[self.slotId_j], X_h[self.slotId_i] == X_h[self.slotId_j] + self.numSlot_j)

# Soft Constraint
eq = if_then(logical_and(X_d[self.slotId_i] == X_d[self.slotId_j], X_h[self.slotId_i] == X_h[self.slotId_j] + self.numSlot_j),
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
eq1 = if_then(logical_not(logical_and(X_d[self.slotId_i] == X_d[self.slotId_j], X_h[self.slotId_i] == X_h[self.slotId_j] + self.numSlot_j)),
    X_penaltiesDoc[index] == (-1)*getIntFromLV_Penalties(vincolo.penalita, TipoPenalty.Docente))
\end{lstlisting}

\end{itemize}