% Input:
% string: string (encoding linear inequalities)
% var: cell array of strings (containing the names of the variables)
% enable_errors: boolean (enables/disables error checks)

% Output:
% C: Matrix
% d: vector

% Description:
% string is the encoding of a polyheder of the form: '-x <= 1 & y + 2z
% == -0.1 & x + y + z >= 4' or similar
% describing the polyheder C*x <= d which is returned by this method. 
% var contains the variable names used in string (e.g. x,y,z,var1,etc)
% This method generates a matrix representation of the equations and
% unequations from string

function [C,d] = transformExplicitPolyhederInputSet(string,var,enable_errors)

if ~isempty(string)
    
lines = splitInput(string,'&');

C = zeros(length(lines),length(var));
d = zeros(length(lines),1);

% define the automaton for parsing
edges =         [1 3 2 0;...
                 1 4 3 0;...
                 1 2 5 0;...
                 1 1 7 0;...
                 2 7 7 0;...
                 2 2 5 1;...
                 2 4 3 0;...
                 3 3 2 1;...
                 3 4 3 0;...
                 3 1 4 0;...
                 3 2 5 1;...
                 3 6 6 1;...
                 4 5 7 0;...
                 4 4 8 0;...
                 5 3 2 2;...
                 5 8 5 0;...
                 5 6 6 2;...
                 5 1 7 0;...
                 8 3 2 1;...
                 8 2 5 1;...
                 8 6 6 1;...
                 8 1 7 0;...
                 8 4 8 0;...
                 6 9 9 0;...
                 6 8 7 0;...
                 6 1 7 0;...
                 6 3 7 0;...
                 9 3 2 3;...
                 9 4 3 3;...
                 9 2 5 3;...
                 9 1 7 3;];
             
expr = {'\.' '[a-z]' '(+|-)' '[0-9]' '(+|-|\.|[a-z]|(<|>|=|#))' '(<|>|=|#)' '(\.|(<|>|=|#))' '\w' '='};

for j=1:1:length(lines)
       
    [memory] = executeAutomaton(simplesyntaxcheck(lines{j}),edges,expr);

    % normalize equation
    pos_del = [];
    %combine vars with const
    for i=1:length(memory)
        if strcmp(memory{i}.type,'var')
            if i-1 > 0 && ~strcmp(memory{i-1}.type,'del')
                %there is a previous symbol (has to be of type const)
                memory{i}.const = memory{i-1}.value;
                memory{i-1} = [];  
            else
                %first symbol in memory (factor has to be 1)
                memory{i}.const = 1;
            end;
        end;
    end;
    memory(cellfun(@isempty,memory)) = [];  %delete empty entries from memory
    
    for i=1:length(memory)
        if strcmp(memory{i}.type,'del')
            pos_del = [pos_del i];
        end;
    end;
    
    % if 2 del symbols are in memory split it and prepare for a second run
    if length(pos_del) == 2
        backup_memory = memory(pos_del(1)+1:end);
        memory = memory(1:pos_del(2)-1);
        pos_del(2) = pos_del(2) - (pos_del(1)) ;
    end;
    
    nextC = size(C,1)+1;
    for i=1:length(pos_del)
        
        
        if i == 2 
            memory = backup_memory; %second run
            nextC = size(C,1)+1;
        else
            nextC = j;
        end;
        
        %bring all vars to left side
        for k =pos_del(i)+1:length(memory)
            if strcmp(memory{k}.type,'var')
                memory{k}.const = -1*memory{k}.const;
            end;
        end;
        
        %bring all const to the right side
        for k =1:pos_del(i)
            if strcmp(memory{k}.type,'const')
                memory{k}.value = -1*memory{k}.value;
            end;
        end;
        
        %sum up all const -> d
        for k =1:length(memory)
            if strcmp(memory{k}.type,'const')
                if nextC <= size(C,1)
                    d(nextC) = d(nextC) + memory{k}.value;
                else
                    d(nextC) = memory{k}.value;
                end;
            end;
        end;
        
        %sum up all equaly named variables -> C
        %sum = cell(length(var),1);
        for k=1:length(var)
            %sum{k} = 0;
            for l=1:length(memory)
                if strcmp('var',memory{l}.type)
                    if strcmp(memory{l}.value,var{k})
                        %sum{k} = sum{k} + memory{l}.const;
                        if nextC <= size(C,1)
                            C(nextC,k) = C(nextC,k) + memory{l}.const;
                        else
                            C(nextC,k) = memory{l}.const;
                        end;
                    end;
                end;
            end;
        end;
        
        %analyze operator (<=, >=, ==)
        %<= -> ok
        %>= -> multiply C and d row with -1
        %== -> double entries (once negated)
        
            if strcmp(memory{pos_del(i)}.value,'<=')
                %
            elseif strcmp(memory{pos_del(i)}.value,'>=')
                C(nextC,:) = -C(nextC,:);
                d(nextC) = -d(nextC);
            else
                % if == guard then add a >= guard
                lastentry = size(C,1);
                C(lastentry+1,:) = -C(nextC,:);
                d(lastentry+1) = -d(nextC);
            end;
        
        
    end;
end;
    
if enable_errors
    % check if for each var there is at least one constraint
    for i=1:length(var)
        if isempty(regexp(string,var{i},'match'))
            error('No constraint containing %s defined!\nPlease add some constraints containing this variable through the gui!\n', var{i});
        end;
    end;    
end;

else
    C = [];
    d = [];
end;

d = reshape(d,length(d),1);