% Input:
% transitions: cell array of structs

% Output:
% transitions: cell array of structs

% Description:
% Removes redundant guards from the model such that redundant intersections
% have not to be computed

% TODO: add further checks ensuring the consistency of the guards
function [transitions] = cleanGuards(transitions)
% normalize guard before the analysis (length 1, round


for k=1:length(transitions)
    
    if ~isempty(transitions{k}.eguards_dir)

        % detect guards containing x == a & x == b with a != b
        [temp_dir,~,ic] = unique(transitions{k}.eguards_dir,'rows');
        
        temp_val = zeros(size(temp_dir,1),1);
        
        for i=1:max(ic)
            x = ic == i;
            if min(transitions{k}.eguards_val(x)) ~= max(transitions{k}.eguards_val(x))
                error('Model contains contradicting equality guards');
            else
                temp_val(i) = min(transitions{k}.eguards_val(x));
            end;
        end;
        
        transitions{k}.eguards_dir = temp_dir;
        transitions{k}.eguards_val = temp_val;
        
        % detect guards containing -x == a & x == b with a != b
        % TODO: reduce redundancies
        for i=1:size(transitions{k}.eguards_dir,1)
            [member,index] = ismember(-transitions{k}.eguards_dir(i,:),transitions{k}.eguards_dir,'rows');
            if member
                % for a direction, there is also the opposite direction
                % contained
                
                if  (transitions{k}.eguards_val(i) ~= -1*transitions{k}.eguards_val(index)) && (transitions{k}.eguards_val(i)~=0 && transitions{k}.eguards_val(index) ~= 0)
                    error('Model contains contradicting equality guards');
                else
                    % there is a redundancy of form x == a & -x == -a
                    
                end;
            end;
        end;
        
    end;   

    if ~isempty(transitions{k}.iguards_dir)

        % keep stronger constraint in a direction and discard the weaker one 
        [temp_dir,~,ic] = unique(transitions{k}.iguards_dir,'rows');
        temp_val = zeros(size(temp_dir,1),1);
        
        for i=1:max(ic)
            x = ic == i;
            temp_val(i) = min(transitions{k}.iguards_val(x));
        end;

        transitions{k}.iguards_dir = temp_dir;
        transitions{k}.iguards_val = temp_val;
        
        % check for impossible guard conditions (only inequality)
        %{
        % difficult to make work
        for i=1:size(transitions{k}.iguards_dir,1)
            [member,index] = ismember(-transitions{k}.iguards_dir(i,:),transitions{k}.iguards_dir,'rows');
            if member
                % for a direction, there is also the opposite direction
                % contained
                
                if  transitions{k}.iguards_val(i) > transitions{k}.iguards_val(index)
                    error('model contains unsolvable guard condition');
                end;
            end;
        end;
        %}
    end;
    
end;