%% Copyright (C) 2012, SRI International.  All Rights Reserved.

%% This program is free software; you can redistribute it and/or
%% modify it under the terms of the GNU General Public License
%% as published by the Free Software Foundation; either version 2
%% of the License, or (at your option) any later version.

%% This program is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%% GNU General Public License for more details.


function [] = createDimensionEqualityFile(modelName)
    
    global subsystemSet;
    subsystemSet = java.util.HashSet;
    
    global variableNameSet;
    variableNameSet = java.util.HashSet;
    
    global subsystemAssertCountMap;
    subsystemAssertCountMap = java.util.Hashtable;
    
    
    global mdlPathName;
    
    global opFile1;
    global opFile2;
    global opFile3;
    global opFile4;
    global opFile5;
    
    opFile1 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_equality_constraints'))), 'w');
    opFile2 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_interface_variables'))), 'w');
    opFile3 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_provided_dimensions'))), 'w');
    opFile4 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_constant_dimensions'))), 'w');
    opFile5 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_subsystems'))), 'w');
    blks = find_system(modelName, 'SearchDepth', '1', 'type', 'Block');
    subsystemSet.clear();
    findDimensions(blks, modelName);
    subsystemSet.clear();
    printTransitions(blks, modelName, modelName);       
    fclose(opFile1);
    fclose(opFile2);
    fclose(opFile3);
    fclose(opFile4);
    fclose(opFile5);
    
    opFile1 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_equality_constraints'))), 'r');
    opFile2 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_interface_variables'))), 'r');
    opFile3 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_provided_dimensions'))), 'r');
    opFile4 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_constant_dimensions'))), 'r');
    opFile5 = fopen(strcat(mdlPathName, strcat('eq/', strcat(modelName, '_subsystems'))), 'r');
    printEqualityFiles();
    fclose(opFile1);
    fclose(opFile2);
    fclose(opFile3);
    fclose(opFile4);
    fclose(opFile5);
end


function [inNames] = getInputNames(handle)
    ports = get_param(handle,'Ports');
    if (ports(1,1) > 0)
        for i = 1:ports(1,1)
            name = regexprep(char(get_param(handle, 'Name')), '\s', '');
            inNames(i) = {strcat(name,'__In',num2str(i))};
        end
    else
        inNames = {};
    end
end


function [outNames] = getOutputNames(handle)
    ports = get_param(handle,'Ports');
    if (ports(1,2) > 0)
        for i = 1:ports(1,2)
            name = regexprep(char(get_param(handle, 'Name')), '\s', '');
            outNames(i) = {strcat(name,'__Out',num2str(i))};
        end
    else
        outNames = {};
    end
end


function [] = findDimensions(blks, sysname)
    global subsystemSet;
    global opFile2;
    global opFile3;
    
    for i=1:length(blks)
         handle = get_param(blks(i),'Handle');
         if iscell(handle)
             handle = handle{1,1};
         end
         name = get_param(blks(i),'Name');
         if iscell(name)
             name = name{1,1};
         end
         name = regexprep(name, '\s', '');
         parent = get_param(blks(i), 'Parent');
         if iscell(parent)
             parent = parent{1,1};
         end
         parent = regexprep(parent, '\s', '');
         parent = regexprep(parent, '/', '__');
         typestr = char(get_param(blks(i),'BlockType'));
         switch typestr
             case 'SubSystem'    
                 if not(subsystemSet.contains(name))
                     subsystemSet.add(name);
                     link_status = get_param(handle,'LinkStatus');
                     if strcmp(link_status,'none') || strcmp(link_status,'inactive')
                         subBlks = find_system(handle, 'SearchDepth', '1', 'type', 'Block');
                         sysPath = sprintf('%s__%s', parent, name);
                         findDimensions(subBlks(2:length(subBlks)), sysPath);
                     end
                 end
         end
    end
    
    fprintf(opFile2,'%s\n', sysname);
    fprintf(opFile3,'%s\n', sysname);

    
    for i=1:length(blks)
        handle = get_param(blks(i),'Handle');
        if iscell(handle)
             handle = handle{1,1};
        end
        type = get_param(blks(i),'BlockType');
        typestr = char(type);
        if strcmp(typestr, 'SubSystem') == 1
            printDimensionInfo(handle);
        end
    end
    for i=1:length(blks)
        handle = get_param(blks(i),'Handle');
        if iscell(handle)
             handle = handle{1,1};
        end
        type = get_param(blks(i),'BlockType');
        typestr = char(type);
        
        if strcmp(typestr, 'SubSystem') == 0
            printDimensionInfo(handle);
        end
    end  
    fprintf(opFile2,'end\n\n\n');
    fprintf(opFile3,'end\n\n\n');
end
    
    
function printDimensionInfo(handle)
     
    global opFile2;
    global opFile3;
    
    link_status = get_param(handle,'LinkStatus');
    parent = get_param(handle, 'Parent');
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    masktype = '';
    stateflowFlag = 0;
    try masktype = char(get_param(handle, 'MaskType')); catch end
    if strcmp(masktype, 'Stateflow')
        stateflowFlag = 1;
    end
   
        % Stateflow is handled separately as non-interface blocks
    if strcmp(get_param(handle, 'blockType'),'SubSystem') && ...
        (strcmp(link_status,'none') || strcmp(link_status,'inactive')) && ...
        (strcmp(masktype, 'Stateflow') == 0)    
        % An invariant on the inputs of the subsystem can be added in yices
        % input format, for example, (assert (= In1 In2))
        % In the input names there should not be any space.
        subsystemName = regexprep(char(get_param(handle, 'Name')), '\s', '');
        name1 = strcat(strcat(parent, '__'), subsystemName);
        blks = find_system(handle,'SearchDepth','1', 'BlockType', 'Inport');
        for i= 1:length(blks) 

            desc = char(get_param(blks(i), 'Description'));    
            name2 = regexprep(char(get_param(blks(i),'Name')), '\s', '');
            inPort = strcat(name1,'__', name2);
            fprintf(opFile2, '%s\n', inPort);
            if strcmp(desc, '') == 0
                fprintf(opFile3, '%s\n', inPort);
            end
        end 
        
        blks = find_system(handle,'SearchDepth','1', 'BlockType', 'Outport');
        for i= 1:length(blks)
            desc = char(get_param(blks(i), 'Description'));
            name2 = regexprep(char(get_param(blks(i),'Name')), '\s', '');
            outPort = strcat(name1, '__', name2);
            fprintf(opFile2, '%s\n', outPort);
            if strcmp(desc, '') == 0
                fprintf(opFile3, '%s\n', outPort);
            end
        end
    else
        name = char(get_param(handle, 'Name'));
        name = regexprep(name, '\s', '');
        desc = char(get_param(handle, 'Description'));
        blocktype = char(get_param(handle,'BlockType'));
        
        if strcmp(blocktype, 'Inport') == 1 || ...
           strcmp(blocktype, 'Sin') == 1 || ...
           strcmp(blocktype, 'Step') == 1 || ...
           strcmp(blocktype, 'FromWorkspace') == 1 || ...
           strcmp(blocktype, 'From') == 1 || ...
           strcmp(blocktype, 'Ground') == 1
            outputNames = getOutputNames(handle);
            if strcmp(parent, '')
                outPortKey = char(outputNames(1));
            else
                outPortKey = strcat(parent, '__', char(outputNames(1)));
            end
            fprintf(opFile2, '%s\n', outPortKey);
            if strcmp(desc, '') == 0
                fprintf(opFile3, '%s\n', outPortKey); 
            end
        elseif strcmp(blocktype, 'Outport') == 1 || ...
               strcmp(blocktype, 'Scope') == 1 || ...
               strcmp(blocktype, 'Terminator') == 1 || ...
               strcmp(blocktype, 'Goto') == 1 || ...
               strcmp(blocktype, 'Display') == 1 || ...
               strcmp(blocktype, 'ToWorkspace') == 1
            inputNames = getInputNames(handle);
            if strcmp(parent, '')
                inPortKey = char(inputNames(1));
            else
                inPortKey = strcat(parent, '__', char(inputNames(1)));
            end
            fprintf(opFile2, '%s\n', inPortKey);
            if strcmp(desc, '') == 0
                fprintf(opFile3, '%s\n', inPortKey);
            end
        elseif strcmp(blocktype, 'Constant') == 1
            outputNames = getOutputNames(handle);
            if strcmp(parent, '')
                outPortKey = char(outputNames(1));
            else
                outPortKey = strcat(parent, '__', char(outputNames(1)));
            end
            fprintf(opFile2, '%s\n', outPortKey);
            if strcmp(desc, '') == 0
                fprintf(opFile3, '%s\n', outPortKey);
            end
        elseif strcmp(blocktype, 'Gain') == 1
            if strcmp(parent, '')
                constantKey = strcat(name, '__Constant');
            else
                constantKey = strcat(parent, '__', name, '__Constant');
            end
            fprintf(opFile2, '%s\n', constantKey);
            if strcmp(desc, '') == 0
                fprintf(opFile3, '%s\n', constantKey);
            end
        elseif strcmp(blocktype, 'Switch') == 1
            if strcmp(parent, '')
                thresholdKey = strcat(name, '__Threshold');
            else
                thresholdKey = strcat(parent, '__', name, '__Threshold');
            end
            fprintf(opFile2, '%s\n', thresholdKey);
            if strcmp(desc, '') == 0
                fprintf(opFile3, '%s\n', thresholdKey);
            end
        end
    end     
end
 


function desc = getDimensionDefinition(block, desc)
    desc = regexprep(desc, '\n','');
    desc = regexprep(desc, '\s+', ' ');
    pos1 = strfind(desc, 'begin dimension');
    if isempty(pos1)
        %fprintf('Error: "begin dimension" cannot be found in the dimension definition of block %s\n', block);
    else
        components1 = regexp(desc, 'begin dimension', 'split');
        pos2 = strfind(desc, 'end dimension');
        if isempty(pos2)
            fprintf('Error: "end dimension" cannot be found in the dimension definition of block %s\n', block);
        else
            components2 = regexp(components1{1,2}, 'end dimension', 'split');
            desc = components2{1,1};
        end
    end
end
 
 
 function [] = printTransitions(blks, syspath, modelName)

    global subsystemSet;
    global opFile1;
    global opFile4;
    global opFile5;
    
    for i=1:length(blks)
        handle = get_param(blks(i),'Handle');
        if iscell(handle)
            handle = handle{1,1};
        end
        name = get_param(blks(i),'Name');
        if iscell(name)
            name = name{1,1};
        end
        name = regexprep(name, '\s', '');
        parent = get_param(blks(i), 'Parent');
        if iscell(parent)
            parent = parent{1,1};
        end
        parent = regexprep(parent, '\s', '');
        type = get_param(blks(i),'BlockType');
        typestr = char(type);
        switch typestr
            case 'SubSystem'
                if not(subsystemSet.contains(name))
                    subsystemSet.add(name);
                    link_status = get_param(handle,'LinkStatus');
                    if (strcmp(link_status,'none') || strcmp(link_status,'inactive'))
                        subBlks = find_system(handle, 'SearchDepth', '1', 'type', 'Block');
                        sysPath = sprintf('%s/%s', parent, name);
                        printTransitions(subBlks(2:length(subBlks)), sysPath, modelName);
                    end
                end
        end
    end
 
    sysname = regexprep(syspath, '/', '__');
    fprintf(opFile5,'%s\n', sysname);
    fprintf(opFile1,'%s\n', sysname);
    fprintf(opFile4,'%s\n', sysname);
    
    for i=1:length(blks)
        handle = get_param(blks(i),'Handle');
        if iscell(handle)
            handle = handle{1,1};
        end
        printBlockInfo(handle, modelName);
    end

    printLineInfo(syspath);
    fprintf(opFile1, 'end\n\n\n');
    fprintf(opFile4, 'end\n\n\n');
 end
 
 
 function printLineInfo(sysPath)

     global transition;
     global opFile1;
    
     sigtrans = '';
     getSignalTransitions(sysPath, '1');
     keys = transition.keySet();
     k = keys.iterator();
     while(k.hasNext())
         key = k.next();
         x  =  transition.get(key);
         for i = 1:x.size()
             str1 = x.get(i-1);
             str2 = key;
         
             str3 = regexp(str1, '__', 'split');    %This may be wrong
             
             dims = size(str3);
             
             if dims(1,2) > 1
                 if strcmp(str3{1,2}, 'ifaction') == 0
                     sigtrans = sprintf('%s\n(= %s %s)', sigtrans, str1, str2);
                 end
             else
                 sigtrans = sprintf('%s\n(= %s %s)', sigtrans, str1, str2);
             end
         end
     end

     fprintf(opFile1,'%s\n', sigtrans);
 end

 
function printBlockInfo(handle, modelName)

     global opFile1;
     global opFile4;
     
     type = char(get_param(handle, 'BlockType'));
     
     name = char(get_param(handle, 'Name'));
     name = regexprep(name, '\s', '');
     parent = char(get_param(handle, 'Parent'));
     parent = regexprep(parent, '\s', '');
     parent = regexprep(parent, '/', '__');
     

     switch type
         
         % Sources and Sinks
         case {'Constant'}
         case {'Inport', 'Sin', 'Step', 'FromWorkspace', 'From', 'Ground'}
         case {'Outport', 'Scope', 'Terminator', 'Goto', 'Display', 'ToWorkspace'}
             
         % User-Defined Functions
         case {'Fcn', 'S-Function'}
             
         % Ports & Subsystems
         case {'SubSystem', 'If', 'EnablePort', 'TriggerPort', 'ActionPort'}
             
         % Signal Routing    
         case {'BusSelector'}
             
         % Lookup Tables
         case {'Lookup'}
             
         % Math Operations
         case {'Abs'}   % same as Memory
             printMemory(handle, opFile1);
         case {'UnaryMinus'}    % same as Memory
             printMemory(handle, opFile1);
         case {'Sum'}
             printSum(handle, opFile1);
         case {'Product'}
             printProduct(handle, opFile1);
         case {'Gain'}
             printGain(handle, opFile1);
         case {'DotProduct'}
             printDotProduct(handle, opFile1);
         case {'MinMax'}
             printMinMax(handle, opFile1);
         case {'Trigonometry'}
             printConstantOutputDimension(handle, opFile4);
         case {'Concatenate'}
             printConcatenate(handle, opFile1);
         case {'Reshape'}
             printReshape(handle, opFile1);
         case {'Signum'}    % same as Relay
             printConstantOutputDimension(handle, opFile4);

             
         % Logic and Bit Operations
         case {'Logic'}
             printConstantOutputDimension(handle, opFile4);
         case {'RelationalOperator'}
             printRelationalOperator(handle, opFile1);
             printConstantOutputDimension(handle, opFile4);
         case {'CombinatorialLogic'}
             printConstantInputDimension(handle, opFile4);
             printConstantOutputDimension(handle, opFile4);
             
         % Signal Routing    
         case {'Switch'}
             printSwitch(handle, opFile1);
         case {'MultiPortSwitch'}
             printMultiPortSwitch(handle, opFile1);
         case {'Mux'}
             printMux(handle, opFile1);
         case {'Demux'}
             printDemux(handle, opFile1);
         case {'Selector'}
             printSelector(handle, opFile1);
         case {'Merge'}     % same as Sum
             printSum(handle, opFile1);
             
         % Signal Attributes
         case {'InitialCondition'}  
             printMemory(handle, opFile1);
             
         % Discrete    
         case {'Memory'} 
             printMemory(handle, opFile1);
         case {'UnitDelay'}     %same as Memory
             printMemory(handle, opFile1);
         case {'DiscreteIntegrator'}    % same as Integrator
             printIntegrator(handle, opFile1);
             
         % Continuous    
         case {'Integrator'} 
             printIntegrator(handle, opFile1);
             
         % Discontinuous
         case {'Saturate'}
             printSaturate(handle, opFile1);
         case {'Relay'}   
             printConstantOutputDimension(handle, opFile4);
         case {'HitCross'}  % same as Relay 
             printConstantOutputDimension(handle, opFile4);
             
         % Ports & Subsystems
         case {'Reference'}
             printReference(handle, modelName, opFile);
         otherwise
             fprintf('The block %s_%s of type %s is not supported..\n', parent, name, type);
     end
end
 

function [] = printConstantInputDimension(handle, opfile)
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    inputNames = getInputNames(handle);
    if strcmp(parent, '')
        inPortKey = char(inputNames(1));
    else
        inPortKey = strcat(parent, '__', char(inputNames(1)));
    end
    fprintf(opfile, '%s\n', inPortKey);
end


function [] = printConstantOutputDimension(handle, opfile)
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    outputNames = getOutputNames(handle);
    if strcmp(parent, '')
        outPortKey = char(outputNames(1));
    else
        outPortKey = strcat(parent, '__', char(outputNames(1)));
    end
    fprintf(opfile, '%s\n', outPortKey);
end


function [] = printSum(handle, opfile)  
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');

    inNames = getInputNames(handle);
    outNames = getOutputNames(handle);
    fprintf(opfile,'(= %s__%s %s__%s)\n', parent, char(outNames(1)), parent, char(inNames(1)));

    ports = get_param(handle,'Ports');
    for i = 2:ports(1,1)
        fprintf(opfile,'(= %s__%s %s__%s))\n', parent, char(inNames(1)), parent, char(inNames(i)));
    end
end


function [] = printProduct(handle, opfile)  
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');

    inNames = getInputNames(handle);
    outNames = getOutputNames(handle);
    fprintf(opfile,'(= %s__%s %s__%s)\n', parent, char(outNames(1)), parent, char(inNames(1)));
end


function [] = printGain(handle, opfile)
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    portOut = sprintf('%s__%s%s', parent, name,'__Out1');
    portConstant = sprintf('%s__%s%s', parent, name,'__Constant');
    fprintf(opfile, '(= %s %s)\n', portOut, portConstant);
end
    

function [] = printDotProduct(handle, opfile)
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');

    inNames = getInputNames(handle);
    
    fprintf(opfile, '(= %s__%s %s__%s)\n', parent, char(inNames(1)), parent, char(inNames(2)));
end



function [] = printMinMax(handle, opfile)
    
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');

    inNames = getInputNames(handle);
    portOut = sprintf('%s__%s%s', parent, name,'__Out1');
        
    ports = get_param(handle,'Ports');
    for i = 1:ports(1,1)
        fprintf(opfile, '(= %s %s__%s)\n', portOut, parent, char(inNames(i)));
    end

    for i = 1 : ports(1,1)
        for j = (i + 1) : ports(1,1)
            fprintf(opfile, '(= %s__%s %s__%s)\n', parent, char(inNames(i)), parent, char(inNames(j)));
        end
    end
end


function [] = printConcatenate(handle, opfile)
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    portIn1 = sprintf('%s__%s__In1', parent, name);
    portOut = sprintf('%s__%s__Out1', parent, name);
    
    fprintf(opfile, '(= %s %s)\n', portOut, portIn1);
end


function [] = printReshape(handle, opfile)    
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    portIn = sprintf('%s__%s__In1', parent, name);
    portOut = sprintf('%s__%s__Out1', parent, name);
    
    fprintf(opfile, '(= %s %s)\n', portOut, portIn);
end


function [] = printRelationalOperator(handle, opfile)
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');

    inNames = getInputNames(handle);
    ports = get_param(handle,'Ports');
    for i = 1 : ports(1,1)
        for j = i + 1 : ports(1,1)
            fprintf(opfile,'(= %s__%s %s__%s)\n', parent, char(inNames(i)), parent, char(inNames(j)));
        end
    end
end



function [] = printSwitch(handle, opfile)
    
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    portIn1 = sprintf('%s__%s__In1', parent, name);
    portIn2 = sprintf('%s__%s__In2', parent, name);
    portIn3 = sprintf('%s__%s__In3', parent, name);
    portOut = sprintf('%s__%s__Out1', parent, name);
               
    fprintf(opfile,'(= %s %s)\n', portIn1, portIn3);
    fprintf(opfile, '(= %s %s__%s__Threshold)\n', portIn2, parent, name);
    fprintf(opfile,'(= %s %s)\n', portOut, portIn1);
end



function [] = printMultiPortSwitch(handle, opfile )
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    inNames = getInputNames(handle);
    outNames = getOutputNames(handle);

    fprintf(opfile,'(= %s__%s %s__%s)\n', parent, char(outNames(1)), parent, char(inNames(2)));

    ports = get_param(handle,'Ports');
    for i = 3:ports(1,1)
        fprintf(opfile,'(= %s__%s %s__%s)\n', parent, char(inNames(2)), parent, char(inNames(i)));
    end;
end



function [] = printMux(handle, opfile)
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    inNames = getInputNames(handle);
    portOut = sprintf('%s__%s%s', parent, name, '__Out1');
    portIn1 = sprintf('%s__%s', parent, char(inNames(1)));
    fprintf(opfile, '(= %s %s)\n', portOut, portIn1);
end


function [] = printDemux(handle, opfile)    
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    portIn = sprintf('%s__%s%s', parent, name, '__In1');
    outNames = getOutputNames(handle);
    portOut1 = sprintf('%s__%s', parent, char(outNames(1)));
    fprintf(opfile, '(= %s %s)\n', portOut1, portIn);
end


function [] = printSelector(handle, opfile)    
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    portIn = sprintf('%s__%s__In1', parent, name);
    portOut = sprintf('%s__%s__Out1', parent, name);
    
    fprintf(opfile, '(= %s %s)\n', portOut, portIn);
end



function [] = printMemory(handle, opfile)  
    
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    portIn = sprintf('%s__%s%s', parent, name, '__In1');
    portOut = sprintf('%s__%s%s', parent, name,'__Out1');
    fprintf(opfile,'(= %s %s)\n', portOut, portIn);
end


function [] = printIntegrator(handle, opfile) 
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    portIn = sprintf('%s__%s%s', parent, name, '__In1');
    portInit = sprintf('%s__%s%s', parent, name, '__In2');
    portOut = sprintf('%s__%s%s', parent, name,'__Out1');

    fprintf(opfile, '(= %s %s)\n', portOut, portIn);
    if strcmp(char(get_param(handle, 'InitialConditionSource')), 'external')
        fprintf(opfile, '(assert+ (= %s %s))\n', portOut, portInit);
    end
end


function [] = printSaturate(handle, opfile)
    
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    portIn1 = sprintf('%s__%s%s', parent, name, '__In1');
    portOut = sprintf('%s__%s%s', parent, name,'__Out1');
    fprintf(opfile,'(= %s %s)\n', portOut, portIn1);
end



function [] = printReference(handle, opfile)
     
    name = char(get_param(handle, 'Name'));
    name = regexprep(name, '\s', '');
    parent = char(get_param(handle, 'Parent'));
    parent = regexprep(parent, '\s', '');
    parent = regexprep(parent, '/', '__');
    
    switch char(get_param(handle, 'SourceType'))
        case 'Cross Product'
            portIn1 = sprintf('%s__%s%s', parent, name, '__In1');
            portIn2 = sprintf('%s__%s%s', parent, name, '__In2');
            portOut = sprintf('%s__%s%s', parent, name,'__Out1');

            fprintf(opfile,'(= %s %s)\n', portOut, portIn1);
            fprintf(opfile,'(= %s__%s %s__%s)\n', portIn1, portIn2);
        otherwise
            printf('Reference block %s is not supported', char(get_param(handle, 'SourceType')));
    end
end


function [] = printEqualityFiles()

    global mdlPathName;
    global opFile;
    global opFile1;
    global opFile2;
    global opFile3;
    global opFile4;
    global opFile5;
    
    sysname = fgets(opFile5);
    while sysname ~= -1
        opFile = fopen(strcat(mdlPathName, strcat('eq/', strcat(sysname, '_equ_constraints'))), 'w');
        line = fgets(opFile1);
        while(strcmp(line, sysname) == 0)
            line = fgets(opFile1);
        end;
        line = fgets(opFile1);
        while(strncmp(line, 'end', 3) == 0)
            fprintf(opFile, '%s', line);
            line = fgets(opFile1);
        end
        fprintf(opFile, '\n\n');
        fclose(opFile);
        
        opFile = fopen(strcat(mdlPathName, strcat('eq/', strcat(sysname, '_interface_vars'))), 'w');
        line = fgets(opFile2);
        while(strcmp(line, sysname) == 0)
            line = fgets(opFile2);
        end;
        line = fgets(opFile2);
        while(strncmp(line, 'end', 3) == 0)
            fprintf(opFile, '%s', line);
            line = fgets(opFile2);
        end
        fprintf(opFile, '\n\n');
        fclose(opFile);
        
        opFile = fopen(strcat(mdlPathName, strcat('eq/', strcat(sysname, '_provided_dims'))), 'w');
        line = fgets(opFile3);
        while(strcmp(line, sysname) == 0)
            line = fgets(opFile3);
        end;
        line = fgets(opFile3);
        while(strncmp(line, 'end', 3) == 0)
            fprintf(opFile, '%s', line);
            line = fgets(opFile3);
        end
        fprintf(opFile, '\n\n');
        fclose(opFile);
        
        opFile = fopen(strcat(mdlPathName, strcat('eq/', strcat(sysname, '_constant_dims'))), 'w');
        line = fgets(opFile4);
        
        while(strcmp(line, sysname) == 0)
            line = fgets(opFile4);
        end;
        line = fgets(opFile4);
        while(strncmp(line, 'end', 3) == 0)
            fprintf(opFile, '%s', line);
            line = fgets(opFile4);
        end
        fprintf(opFile, '\n\n');
        fclose(opFile);
        
        
        sysname = fgets(opFile5);
    end
end