GLPK/Cross Platform IDEs

This page lists cross-platform integrated development environments — in most cases, Windows, Mac OS X, and Linux. Not all IDEs support MathProg programming however.


jEdit edit

jEdit 5 is a cross-platform programming editor that supports GLPK. See this November 2012 post for more details.

Coliop project edit

Coliop3 is an IDE (Integrated Development Environment) for solving linear (LP) and mixed integer programming (MIP) problems. This project contains CMPL (Coliop mathematical programming language) and uses GLPK as the solver.

CMPL is a mathematical programming language for modelling linear programming (LP) problems or mixed integer programming (MIP) problems. The CMPL syntax is similar in formulation to the original mathematical model but also includes syntactic elements from modern programming languages. CMPL is intended to combine the clarity of mathematical models with the flexibility of programming languages.

Coliop3 and CMPL are projects of the Technical University of Applied Sciences Wildau and the Institute for Operations Research and Business Management at the Martin Luther University Halle-Wittenberg, both of Germany.

Coliop3 and CMPL are open source projects, licensed under GPL, and available for Linux, Mac OS X and Microsoft Windows.

Sublime Text 2 edit

Sublime Text 2 is a powerful commercial editor for Windows, Linux and OS X. The following script defines the syntax highlighting for GNU MathProg using all of the symbols and control tokens found in the 4.47 GLPK version of MathProg. The following plist syntax definition file can simply be added to the Sublime Text 2 Packages/User directory on the host platform and then restart the Sublime editor. The syntax highlighting is defined by default for .mod and .dat files.

Syntax highlighting of parameters, variables and sets is challenging for any editor and to distinguish between params, vars and sets, a naming convention has to be used. The code below uses the following naming convention so that the parameters, variables and sets can be readily discerned.

  set regexp:        [A-Z][A-Z0-9_]+     eg. SWAP_CONTRACTS      [c constant convention]
  params regexp:     [A-Z][A-Za-z0-9_]+  eg. DailyGenerationCost [CamelCase] 

The JSON format code used to create the plist file is included below and the plist code itself can be edited to implement your own naming convention or any other changes.

GMPL.tmLanguage
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>fileTypes</key>
	<array>
		<string>mod</string>
		<string>dat</string>
	</array>
	<key>name</key>
	<string>GNU MathProg</string>
	<key>patterns</key>
	<array>
		<dict>
			<key>include</key>
			<string>#comments</string>
		</dict>
		<dict>
			<key>match</key>
			<string>\b(set|setof|param|var)\b</string>
			<key>name</key>
			<string>support.class.gmpl</string>
		</dict>
		<dict>
			<key>match</key>
			<string>\b(&amp;&amp;|and|by|sum|prod|exists|cross|diff|div|in|Infini|inter|less|mod|not|dimen|or|\|\||symdiff|union|within|OUT|IN)\b</string>
			<key>name</key>
			<string>keyword.operator.gmpl</string>
		</dict>
		<dict>
			<key>match</key>
			<string>\b(data|end|display|for|forall|else|if|then|solve|maximize|minimize|table|check|subj(?:ect)?\s+to)\b</string>
			<key>name</key>
			<string>keyword.control.gmpl</string>
		</dict>
		<dict>
			<key>comment</key>
			<string>separate definition as . matches \b</string>
			<key>match</key>
			<string>\s*(s\.t\.)\s+</string>
			<key>name</key>
			<string>keyword.control.gmpl</string>
		</dict>
		<dict>
			<key>match</key>
			<string>\b(binary|integer|symbolic)\b</string>
			<key>name</key>
			<string>support.type.gmpl</string>
		</dict>
		<dict>
			<key>match</key>
			<string>\b(printf|abs|ceil|floor|exp|log|log10|max|min|sqrt|sin|cos|atan|atan2|round|trunc|Irand224|Uniform0|Uniform|Normal01|Normal|card|length|substr|str2time|time2str|gmtime)\b</string>
			<key>name</key>
			<string>support.function.gmpl</string>
		</dict>
		<dict>
			<key>match</key>
			<string>\b(true|false|TRUE|FALSE|xBASE|i?ODBC|MySQL|CSV)\b</string>
			<key>name</key>
			<string>constant.language.gmpl</string>
		</dict>
		<dict>
			<key>match</key>
			<string>\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\.?[0-9]*)|(\.[0-9]+))((e|E)(\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\b</string>
			<key>name</key>
			<string>constant.numeric.gmpl</string>
		</dict>
		<dict>
			<key>comment</key>
			<string>set CONSTANT idiom</string>
			<key>match</key>
			<string>\b[A-Z][A-Z0-9_]+\b</string>
			<key>name</key>
			<string>constant.character.gmpl</string>
		</dict>
		<dict>
			<key>comment</key>
			<string>variable idiom</string>
			<key>match</key>
			<string>\b[A-Z][A-Za-z0-9_]+\b</string>
			<key>name</key>
			<string>variable.other.gmpl</string>
		</dict>
		<dict>
			<key>begin</key>
			<string>"</string>
			<key>beginCaptures</key>
			<dict>
				<key>0</key>
				<dict>
					<key>name</key>
					<string>punctuation.definition.string.begin.gmpl</string>
				</dict>
			</dict>
			<key>end</key>
			<string>"</string>
			<key>endCaptures</key>
			<dict>
				<key>0</key>
				<dict>
					<key>name</key>
					<string>punctuation.definition.string.end.gmpl</string>
				</dict>
			</dict>
			<key>name</key>
			<string>string.quoted.double.gmpl</string>
			<key>patterns</key>
			<array>
				<dict>
					<key>include</key>
					<string>#string_escaped_char</string>
				</dict>
				<dict>
					<key>include</key>
					<string>#string_placeholder</string>
				</dict>
			</array>
		</dict>
		<dict>
			<key>begin</key>
			<string>'</string>
			<key>beginCaptures</key>
			<dict>
				<key>0</key>
				<dict>
					<key>name</key>
					<string>punctuation.definition.string.begin.gmpl</string>
				</dict>
			</dict>
			<key>end</key>
			<string>'</string>
			<key>endCaptures</key>
			<dict>
				<key>0</key>
				<dict>
					<key>name</key>
					<string>punctuation.definition.string.end.gmpl</string>
				</dict>
			</dict>
			<key>name</key>
			<string>string.quoted.single.gmpl</string>
			<key>patterns</key>
			<array>
				<dict>
					<key>include</key>
					<string>#string_escaped_char</string>
				</dict>
			</array>
		</dict>
	</array>
	<key>repository</key>
	<dict>
		<key>comments</key>
		<dict>
			<key>patterns</key>
			<array>
				<dict>
					<key>begin</key>
					<string>/\*</string>
					<key>end</key>
					<string>\*/</string>
					<key>name</key>
					<string>comment.block.gmpl</string>
				</dict>
				<dict>
					<key>match</key>
					<string>\*/.*\n</string>
					<key>name</key>
					<string>invalid.illegal.stray-comment-end.gmpl</string>
				</dict>
				<dict>
					<key>begin</key>
					<string>#</string>
					<key>end</key>
					<string>$\n?</string>
					<key>name</key>
					<string>comment.line.number-sign.gmpl</string>
				</dict>
				<dict>
					<key>begin</key>
					<string>//</string>
					<key>end</key>
					<string>$\n?</string>
					<key>name</key>
					<string>comment.line.double-slash.gmpl</string>
				</dict>
			</array>
		</dict>
		<key>string_escaped_char</key>
		<dict>
			<key>patterns</key>
			<array>
				<dict>
					<key>match</key>
					<string>\\(\\|[abefnprtv'"?]|[0-3]\d{,2}|[4-7]\d?|x[a-fA-F0-9]{,2}|u[a-fA-F0-9]{,4}|U[a-fA-F0-9]{,8})</string>
					<key>name</key>
					<string>constant.character.escape.gmpl</string>
				</dict>
				<dict>
					<key>match</key>
					<string>\\.</string>
					<key>name</key>
					<string>invalid.illegal.unknown-escape.gmpl</string>
				</dict>
			</array>
		</dict>
		<key>string_placeholder</key>
		<dict>
			<key>patterns</key>
			<array>
				<dict>
					<key>match</key>
					<string>(?x)%
    						(\d+\$)?                             # field (argument #)
    						[#0\- +']*                           # flags
    						[,;:_]?                              # separator character (AltiVec)
    						((-?\d+)|\*(-?\d+\$)?)?              # minimum field width
    						(\.((-?\d+)|\*(-?\d+\$)?)?)?         # precision
    						(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)? # length modifier
    						[diouxXDOUeEfFgGaACcSspn%]           # conversion type
    					</string>
					<key>name</key>
					<string>constant.other.placeholder.gmpl</string>
				</dict>
				<dict>
					<key>match</key>
					<string>%</string>
					<key>name</key>
					<string>invalid.illegal.placeholder.gmpl</string>
				</dict>
			</array>
		</dict>
	</dict>
	<key>scopeName</key>
	<string>source.gmpl</string>
	<key>uuid</key>
	<string>1d90942b-6776-498d-9d0e-311525879872</string>
</dict>
</plist>

To implement larger changes, the following JSON syntax file is much easier to edit than the xml plist file, but you will need the AAAPackageDev package loaded into the Sublime editor. The complete instructions for converting the JSON format file to xml plist format can be found at Sublime text 2 syntax definitions.

GMPL.JSON-tmLanguage
{ 
  "name": "GNU MathProg",
  "scopeName": "source.gmpl",
  "fileTypes": [
    "mod",
    "dat"
  ],
  "patterns": [
    {
      "include": "#comments"
    }, 
    { 
      "match": "\\b(set|setof|param|var)\\b",
      "name": "support.class.gmpl"
    },
    {
      "match": "\\b(&&|and|by|sum|prod|exists|cross|diff|div|in|Infini|inter|less|mod|not|dimen|or|\\|\\||symdiff|union|within|OUT|IN)\\b", 
      "name": "keyword.operator.gmpl"
    },
    {
      "match": "\\b(data|end|display|for|forall|else|if|then|solve|maximize|minimize|table|check|subj(?:ect)?\\s+to)\\b", 
      "name": "keyword.control.gmpl"
    },
    {
      "match": "\\s*(s\\.t\\.)\\s+",
      "name": "keyword.control.gmpl",
      "comment": "separate definition as . matches \\b"
    },
    {
      "match": "\\b(binary|integer|symbolic)\\b", 
      "name": "support.type.gmpl"
    },
    {
      "match": "\\b(printf|abs|ceil|floor|exp|log|log10|max|min|sqrt|sin|cos|atan|atan2|round|trunc|Irand224|Uniform0|Uniform|Normal01|Normal|card|length|substr|str2time|time2str|gmtime)\\b", 
      "name": "support.function.gmpl"
    },    
    {
      "match": "\\b(true|false|TRUE|FALSE|xBASE|i?ODBC|MySQL|CSV)\\b", 
      "name": "constant.language.gmpl"
    }, 
    {
      "match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b", 
      "name": "constant.numeric.gmpl"
    }, 
    {
      "comment": "set CONSTANT idiom",
      "match": "\\b[A-Z][A-Z0-9_]+\\b",
      "name": "constant.character.gmpl"
    }, 
    {
      "comment": "variable idiom",
      "match": "\\b[A-Z][A-Za-z0-9_]+\\b", 
      "name": "variable.other.gmpl"
    }, 
    {
      "begin": "\"", 
      "beginCaptures": {
        "0": {
          "name": "punctuation.definition.string.begin.gmpl"
        }
      }, 
      "end": "\"", 
      "endCaptures": {
        "0": {
          "name": "punctuation.definition.string.end.gmpl"
        }
      }, 
      "name": "string.quoted.double.gmpl", 
      "patterns": [
        {
          "include": "#string_escaped_char"
        }, 
        {
          "include": "#string_placeholder"
        }
      ]
    }, 
    {
      "begin": "'", 
      "beginCaptures": {
        "0": {
          "name": "punctuation.definition.string.begin.gmpl"
        }
      }, 
      "end": "'", 
      "endCaptures": {
        "0": {
          "name": "punctuation.definition.string.end.gmpl"
        }
      }, 
      "name": "string.quoted.single.gmpl", 
      "patterns": [
        {
          "include": "#string_escaped_char"
        }
      ]
    }
  ],
  "repository": {
    "comments": {
      "patterns": [
        {
          "begin": "/\\*", 
          "end": "\\*/", 
          "name": "comment.block.gmpl"
        }, 
        {
          "match": "\\*/.*\\n", 
          "name": "invalid.illegal.stray-comment-end.gmpl"
        }, 
        {
          "begin": "#", 
          "end": "$\\n?", 
          "name": "comment.line.number-sign.gmpl"
        },
        {
          "begin": "//", 
          "end": "$\\n?", 
          "name": "comment.line.double-slash.gmpl"
        }
      ]
    },
    "string_escaped_char": {
      "patterns": [
        {
          "match": "\\\\(\\\\|[abefnprtv'\"?]|[0-3]\\d{,2}|[4-7]\\d?|x[a-fA-F0-9]{,2}|u[a-fA-F0-9]{,4}|U[a-fA-F0-9]{,8})", 
          "name": "constant.character.escape.gmpl"
        }, 
        {
          "match": "\\\\.", 
          "name": "invalid.illegal.unknown-escape.gmpl"
        }
      ]
    }, 
    "string_placeholder": {
      "patterns": [
        {
          "match": "(?x)%\n    \t\t\t\t\t\t(\\d+\\$)?                             # field (argument #)\n    \t\t\t\t\t\t[#0\\- +']*                           # flags\n    \t\t\t\t\t\t[,;:_]?                              # separator character (AltiVec)\n    \t\t\t\t\t\t((-?\\d+)|\\*(-?\\d+\\$)?)?              # minimum field width\n    \t\t\t\t\t\t(\\.((-?\\d+)|\\*(-?\\d+\\$)?)?)?         # precision\n    \t\t\t\t\t\t(hh|h|ll|l|j|t|z|q|L|vh|vl|v|hv|hl)? # length modifier\n    \t\t\t\t\t\t[diouxXDOUeEfFgGaACcSspn%]           # conversion type\n    \t\t\t\t\t", 
          "name": "constant.other.placeholder.gmpl"
        }, 
        {
          "match": "%", 
          "name": "invalid.illegal.placeholder.gmpl"
        }
      ]
    }
  },
  "uuid": "1d90942b-6776-498d-9d0e-311525879872"
}

Build systems for checking or running GLPK can be added to Sublime Text 2 by defining a build system and adding the build definition file to the Sublime Text 2 Packages/User directory on the host platform with instructions found at Sublime Text 2 build systems. The example below implements a syntax check run of GLPK for the currently edited file on a Windows platform.

GLPK_check.sublime-build
{
  "cmd": ["c:\\glpk\\w64\\glpsol", "-m", "$file", "--check"],
  "working_dir": "$project_path"
}

Other options edit

QSciTE might be a possible IDE in the future, see: http://code.google.com/p/qscite.