記述形式
算術演算子に加えて、簡単、迅速に自身のモデルを構築するために、LocalSolverのモデラーは必須のプログラミング言語を複数提供します。
この言語(LSP言語)は、スクリプト言語の全特徴を持っていますが、問題のモデリングと求解が専門です。注:LSP言語は大文字、小文字を区別して使用します。
基本タイプと割当て
変数宣言が瞬時に行われます。そのためステートメントx=vは値vを変数xに割当てます。変数が型を持たない場合、値は厳しい型となります。:変数は単にコンテナーです。
2つのタイプが明示的に定義されます。
integers (x = 12)とstrings (x = "foo")
ブール型はそれぞれ偽としてコーディングし、真の整数0と1で、黙次的に定義されます。
価値vがモデリング式と一致している場合、左側の矢印は=の代わりに<-を使用する必要があります。このようにして、下記のスタートメントが有効になります。
a = true; // a = 1
b = 9; // b = 9
c = a + b; // c = 10
c = a * b; // c = 9
c = a == b; // c = 0
c = a < b; // c = 1
マップ
マップとはキーに関連付けて値を格納するデータ構造です。
キーは文字列であると同時に、整数(必ずしも連続的ではない)の場合もあります。
値は任意の型で設定できます。
キーに関連付けした値は設定するかカッコ表記を使用します。
: a[9] = "abc", a["abc"] = 9.
マップはその最初の要素を代入する時、暗黙的に宣言されます。または、空のマップは下記のように、map()関数またはブレース{}を使用し定義します。
a = map("z", 9); // a[0] = "z", a[1] = 9
a = {"z", 9}; // a[0] = "z", a[1] = 9
a["a"] = "abc"; // a[0] = "z", a[1] = 9, a["a"] = abc
a[-3] = "xyz"; // a[0] = "z", a[1] = 9, a["a"] = abc, a[-3] = "xyz"
このキーに値が関連付けがない場合、キーに関連付けた値を取り戻すことで、エラーを排除できます。既存のキーに値を設定するには、前に関連付した値に上書きします。
条件文
if (C) S_true; else S_false; が条件ステートメントです。:cが偽(すなわちCが0ならば)、ステートメントS_falseが実行され、条件Cが真(すなわちCが1ならば)ステートメントS_trueが実行されます。注:else ブランチはオプションです。
中括弧{}を使用して1つのステートメントとする代わりにステートメントブロックを宣言することができます。条件付き3ビット演算子?=はショートカットとして使用することもできます。
if (1 < 2) c = 3; else c = 4;
c = 1 < 2 ? 3 : 4;
if (0) c = "ok";
if (true) c = "ok";
if (2) c = "error"; // ERROR: invalid condition
c = 0 * 9; // c = 0
if (c) {
a = "L";
b = 0;
} else { // executed block
a = "S";
b = 1;
}
ループ文
while (C) S; 条件Cが真ならば(すなわちCが1ならば)、ステートメントSは繰り返し実行します。1回目の実行、シンタックスdo S; while (C);は条件cに関係なく一回ステートメントSを実行し、その後、条件が真ならば、Sを繰り返し実行します。
for [v in V] SはステートメントSはVにすべての値を取るVで繰り返し実行されるイタレーション・ループです。そこでは、Vが値域またはマップになります。
値域はfrom及びtoの両方を記述したシンタックスfrom..toで宣言します。
マップを得た場合、イタレーションはキーの増加率に従いマップの値で実行されます。
マップのペア(キー、値)は、for [k,v in M].シンタックスで、繰り返します。
for [i in 0..2] a[i] = i + 1; // a[0] = 1, a[1] = 2, a[2] = 3
s = 0; for [v in a] s = s + v; // s = 6
s = 0; for [k,v in a] s = s + k + v; // s = 9
for [v in V : C]はフィルター処理したイタレーション・ループです・Vは条件Cを満たすVの値のみ取ります。注:ネスト化されたループは下記のように簡潔に記述することができます。
for [i in 0..2] a[i] = i + 1; // a[0] = 1, a[1] = 2, a[2] = 3
s = 0; for [v in a] s = s + v; // s = 6
s = 0; for [k,v in a] s = s + k + v; // s = 9
for [v in V : C]はフィルター処理したイタレーション・ループです・Vは条件Cを満たすVの値のみ取ります。注:ネスト化されたループは下記のように簡潔に記述することができます。
for[i in 0..9]
for [j in i+1..9]
for [k in j+2..9]
a[i][j][k] = i + j + k;
for[i in 0..9][j in i+1..9][k in j+2..9] // compact
a[i][j][k] = i + j + k;
すべてのループ制御文の種類に、ステートメント・ブロックは大括弧を使用し、1つのステートメントの代わりに、宣言を行うことができます。
for[i in 0..9][j in i+1..9][k in j+2..9] {
a[i][j][k] = i + j + k;
b[i][j][k] = i * j * k;
}
割当ての繰り返し
LSP言語の「割り当ての繰り返し」で提供される斬新な機能により、簡潔で理解しやすいモデルを記述することができます。コードfor [v in V] a[v] = f(v);を使用し、簡潔に記述することが可能です。
a[v in V] = f(v); forと同様、イタレーションは、ネスト化し、フィルター処理が可能です。
for[i in 0..9][j in i+1..9][k in j+2..9]
a[i][j][k] = i + j + k;
a[i in 0..9][j in i+1..9][k in j+2..9] = i + j + k; // very compact!
割り当ての繰り返しもまたモデリング表現式を宣言することができます。:x[i in 0..n-1][j in 0..m-1] <- bool();
関数
関数はキーワードfunctionを使用し、宣言します。パラメータ値は括弧で囲い、そのコードは中括弧で囲いカプセル化します。
function isEven(v) {
if (v % 2 == 0) return true;
else return false;
}
値はreturnステートメントを使用する関数で、あらゆるポイントからでも、戻すことが可能です。デフォルトを使用することで、すべての変数の参照有効範囲(変数のスコープ)を広範囲に設定することができ、、プログラム内のどこからでも、それらのブロックにローカル関数およびイタレーション変数(forステートメントに導入された)のパラメータの特例的なアクセスを可能にします。
local キーワードはそのブロック向けに、変数を局所的にするために使用することが可能です。
注:モデリング表現式はローカルに定義することができません。ローカル変数を使用すると、それが同じ名前で別の場所で宣言されている変数によって、副次的障害が生じないことを確認できます。
function computeSumOfEvenNumbers(a,b) {
local total = 0;
for [v in a..b : isEven(v)]
total = total + v;
return total;
}