.. -*- coding: utf-8 -*- 更新履歴 ======== [1.5.0] - 2024-03-28 -------------------- :Added: - :#72: 添字グループ情報 変数の添字グループ情報を指定できるようになりました. メタヒューリスティクスアルゴリズム wls へ,「割当てを意味する変数」の情報を明示的に渡せます. 割当構造をもつ最適化問題に対し,探索性能の向上が見込めます. 詳細は `Variable.group` をご覧ください. - :#82: Python 3.12 対応 Python 3.12 に対応しました. - :#85: 変数の値固定 変数の値を現在値に固定するメソッド `Variable.fix` を追加しました. また,固定した値を解除するメソッド `Variable.unfix` も利用できます. 複数求解を行うときに,変数固定/解除を利用すると便利です. 使用方法については `guide/fix` もご覧ください. - :#89: 添字付き get メソッド get メソッドを Parameter/Variable/Expression/Constraint に追加しました. get メソッドは __getitem__ の KeyError が投げられないバージョンで, key に対応するものがない場合には KeyError が投げられず 0 となります. これにより,境界条件やフローをより簡潔に記述することができるようになります. デフォルト値の指定はできず常に 0 となります. 添字をサポートしないこれまでの Table.get メソッドは削除されました. 詳細は `Parameter.get`, `Variable.get`, `Expression.get`, `Constraint.get` をご確認ください. 使用方法については `guide/get` もご覧ください. >>> i = Element(value=[1, 2, 3], name='i') >>> z = BinaryVariable(index=i, name='z') >>> z[i] - z.get(i-1) >= 1 ((z[i]-z.get((i-1)[i])[i])[i]>=1): z[1]>=1 -z[1]+z[2]>=1 -z[2]+z[3]>=1 - :#90: Parameter/Table の文字列フォーマット指定 添字なし Parameter/Table がフォーマット済み文字リテラル(f-string)に対応しました. 目的関数値を ``f'{problem.objective.val:.2f}'`` のように成形するときなどに便利です. 詳細は `Parameter.__format__` をご確認ください. :Changed: - :#88: wls の連続変数対応 メタヒューリスティクスアルゴリズム wls で `guide/integervariable` だけでなく 連続変数 `guide/variable` を扱えるようになりました. 連続変数を使う際は,目的関数と制約式が線形である必要があります. wls については `guide/metaheuristics` をご覧ください. :Fixed: - :#1221: ネストした Sum でエラーになることがある ネストした Sum で添字が残っている場合に SimpleError になることがある不具合を修正しました. [1.4.1] - 2023-06-15 -------------------- :Fixed: - :#1186: setitem で IndexError になることがある setitem で意図しない IndexError が発生することがある不具合を修正しました. [1.4.0] - 2023-03-27 -------------------- :Added: - :#55: 分枝限定法の終了条件を関数で判定させる 分枝限定法の終了条件を Python のコールバック関数で与えられるようになりました. 詳細は `guide/callback` をご確認ください. >>> def func(solver): ... # 実行可能解の個数が 1 以上になったら分枝限定法を停止する ... if solver['SolutionCount'] >= 1: ... return True ... return False ... >>> problem = Problem() >>> ... >>> problem.setCallback(mip_terminate=func) - :#63: Python 3.11 対応 Python 3.11 に対応しました. :Changed: - :#75: wcsp の一般整数変数対応 制約充足問題に対するメタヒューリスティクスアルゴリズム wcsp で `guide/binaryvariable` だけでなく `guide/integervariable` を使えるようになりました.wcsp については `guide/metaheuristics` をご覧ください. - :#70: NuoptStatus を列挙型にする :py:class:`~pysimple.NuoptStatus` が IntEnum を継承するようになりました. >>> x = BinaryVariable(name='x') >>> p = Problem() >>> p.status >>> print(p.status) NuoptStatus.INITIAL >>> p += x >>> p.solve(silent=True) >>> p += x <= -1 >>> p.solve(silent=True) - :#1113: 求解オプション定数を列挙型にする 求解オプション定数が IntEnum を継承するようになりました.これに伴いクラスの構造が変わります. また,1.4.0 では新旧両方の指定方法で設定ができますが,将来的に従来の指定方法は廃止されます. 値での指定は今後もサポートされます. >>> p = Problem() >>> p.options.branchCut >>> p.options.branchCut = Options.Branch.CUT_AGGRESSIVE # 従来の指定方法 >>> p.options.branchCut 2 >>> p.options.branchCut = Options.Branch.Cut.AGGRESSIVE # バージョン 1.4.0 以降の指定方法 >>> p.options.branchCut >>> p.options.branchCut = 2 # 値で指定も可能(従来通り) >>> p.options.branchCut 2 - :#76: 選択型求解オプションの指定方式統一 求解オプションの ``method`` と ``scaling`` で求解オプション定数が使用できるようになりました. ``method`` は今後とも新旧両方の指定方法がサポートされます. ``scaling`` は 1.4.0 では新旧両方の指定方法で設定ができますが,将来的に従来の文字列による指定方法は廃止されます. >>> p = Problem() >>> p.options.method = 'simplex' # 従来の指定方法 >>> p.options.method 'simplex' >>> p.options.method = Options.Method.SIMPLEX # バージョン 1.4.0 以降の指定方法 >>> p.options.method >>> p.options.scaling = 'cr' # 従来の指定方法 >>> p.options.scaling >>> p.options.scaling = Options.Scaling.CR # バージョン 1.4.0 以降の指定方法 >>> p.options.scaling >>> p.options.scaling = 2 # 値で指定も可能(新規) >>> p.options.scaling 2 :Removed: - :#62: Python 3.8 サポート Python 3.8 は非対応となりました. :Fixed: - :#50: LP の後に wcsp を解けない 連続変数を含む制約式・目的関数を一旦追加すると,最終的に使用していなくても wcsp として求解できなくなる不具合を 修正しました. [1.3.1] - 2022-06-30 -------------------- :Added: - :#6: Parameter と Set の比較 Parameter と Set の比較ができるようになりました. >>> i = Element(value=[1, 2, 3], name='i') >>> S = Set(value=[3, 4], name='S') >>> i < S (i>> i+1 < S ((i+1)[i]>> i+1 < [3, 4] ((i+1)[i]<[3, 4])[i] in [2, 3] >>> a = Parameter(index=i, name='a'); a[i]=i+1 >>> a[i] < S (a[i]>> a[i] < [3, 4] (a[i]<[3, 4])[i] in [2, 3] - :#8: Parameter を含んだ Expression のアクセス `Expression.__getitem__` に Parameter が使用できるようになりました. >>> I = Set(value=[1,2]); i = Element(set=I, name='i') >>> J = Set(value=[3,4]); j = Element(set=J, name='j') >>> x = Variable(index=(i,j), init={ij: sum(ij) for ij in I*J}, name='x') >>> e = x[i,j] + 1 >>> b = Parameter(index=j, value={3: 4, 4: 3}, name='b') >>> e[i, b[j]].val (x[i,j]+1)[i,b[j]][1,3].val=6 (x[i,j]+1)[i,b[j]][1,4].val=5 (x[i,j]+1)[i,b[j]][2,3].val=7 (x[i,j]+1)[i,b[j]][2,4].val=6 :Fixed: - :#1022: 条件文の結果を間違うことがある 修正漏れを再修正しました. - :#1077: メモリリーク メモリリーク箇所の修正を行いました. - :#1085: 実行可能解が見つかっていないのに isFeasible() が True 実行可能解が得られていないにも関わらず `isFeasible` 関数が True になることがある不具合を修正しました. [1.3.0] - 2022-03-28 -------------------- :Added: - :#4: IIS 情報の取得 線形計画問題において互いに矛盾する制約式がある場合,その最小の組を IIS(Irreducible Infeasible Set) と呼びます. この IIS を Python オブジェクトとして取得できるようになりました. 実行不可能な場合に,原因となる制約の特定や,その制約に対するケアなどを自動化する強力な手助けとなります. 詳細は `guide/iis` をご確認ください. >>> x = Variable(name='x', lb=0) >>> y = Variable(name='y', lb=0, ub=1) >>> z = Variable(name='z', lb=0) >>> p = Problem() >>> p += x + y + z >>> p += y + z >= 0, 'cons1' >>> p += x + y >= 5, 'cons2' >>> p += x + z <= 3, 'cons3' >>> p.solve(silent=True) 3 # NuoptStatus.INFEASIBLE >>> p.result.iis 0: cons2: violation=-1 x+y>=5 1: cons3 -x-z>=-3 - :#42: PySIMPLE オブジェクトのシリアライズ PySIMPLE オブジェクトをバイナリにシリアライズできるようになりました. 詳細は `guide/serialize` をご確認ください. >>> i = Element(value=[1, 2, 3], name='i') >>> x = Variable(index=i, name='x') >>> with open('dump.pkl', 'wb') as f: ... Serialize.dump(x, f) ... >>> with open('dump.pkl', 'rb') as g: ... x_ = Serialize.load(g) ... - :#1036: Problem に登録されている変数一覧の取得 Problem クラスに属性 ``variables`` が追加されました. 詳細は :obj:`~pysimple.Problem.variables` をご確認ください. - :#34: Problem の番号アクセス :obj:`~pysimple.Problem.__getitem__` に番号アクセスできるようになりました.負数も使用可能です. `constraints` や :obj:`~pysimple.Problem.variables` も同様のアクセスができます. また,:obj:`~pysimple.Problem.__delitem__` においても同様です. >>> x = Variable(name='x') >>> y = Variable(name='y') >>> p = Problem() >>> p += x >= 1, 'cons1' >>> p += y >= 1, 'cons2' >>> p['cons2'] cons2: y>=1 >>> p[1] cons2: y>=1 >>> p[-1] cons2: y>=1 >>> p.constraints['cons2'] cons2: y>=1 >>> p.constraints[-1] cons2: y>=1 >>> p.variables['y'] y: y >>> p.variables[-1] y: y - :#35: 値の丸め 組み込み関数 ``round`` でパラメータ値や計算結果の値を丸めることができるようになりました. 詳細は `__round__` をご確認ください. >>> p = Problem() : >>> p.solve(silent=True) 1 >>> x.val x[0].val=1.500000000256067 x[1].val=2.9999999999710107 >>> round(x[i].val, 2) round(x[i].val, 2)[0]=1.5 round(x[i].val, 2)[1]=3.0 - :#37: 目的関数の削除 設定した目的関数を del 文で削除することができるようになりました. 詳細は `objective` をご確認ください. >>> x = Variable(name='x') >>> y = Variable(name='y') >>> p = Problem() >>> p += x >>> p.objective x: x >>> p += y pysimple.error.SimpleError: objective can only be assigned once >>> del p.objective >>> p += y >>> p.objective y: y - :#45: Python 3.10 対応 Python 3.10 に対応しました. :Changed: - :#17: 制約種の LP/QP での利用 `guide/weightedconstraint` ハード制約,セミハード制約,ソフト制約を LP/QP の一部解法でも 利用できるようになりました. - :#33: 目的関数の初期値 `objective` の初期値を空の式としました.以前は ``None`` でした. >>> p = Problem() >>> p.objective : 0 - :#56: wcsp/wls で二次の制約 wcsp/wls で二次の制約を扱えるようになりました.`guide/metaheuristics`. - :#57: wls で unbounded な整数変数 wls で整数変数を扱う際に上下限制約がなくても扱えるようになりました.`guide/metaheuristics`. :Removed: - :#46: Python 3.7 サポート Python 3.7 は非対応となりました. [1.2.1] - 2021-06-16 -------------------- :Fixed: - :#919: KeyError のエラーメッセージ Expression 型に対する __getitem__ で発生する KeyError のメッセージを再考しました. メッセージは式の項単位となります. >>> i = Element(value=[1,2], name='i') >>> j = Element(value=[3,4], name='j') >>> x = Variable(index=i, name='x') >>> z = Variable(index=(i,j), name='z') >>> exp = Sum(z[i,j], j) + x[i] >>> exp[0] KeyError: 'Sum(z[i,j], j)[0]' - :#1004: mpsout で整数性が消失するケースがある 変数が制約式にあらわれず,目的関数のみあるいは全くあらわれない場合, :obj:`~pysimple.Problem.mpsout` で出力される mps ファイルにおいて連続変数として記述されるという不具合を修正しました. - :#1007: PySIMPLE の mpsout でファイル名を長くすると mpssolver で読めなくなる :obj:`~pysimple.Problem.mpsout` で指定されたファイル名が長すぎると,仕様を満たさない mps ファイルが出力されるという不具合を修正しました. - :#1013: 範囲関数の空集合が含まれていたときの値 PYSIMPLE-119 で演算結果に添字が残る場合のパラメータの結果を再修正しました. >>> i0 = Element(value=[], name='i0') >>> i1 = Element(value=[1,2], name='i1') >>> a = Parameter(index=(i0,i1), name='a') >>> a # empty >>> Sum(a[i0,i1], i0) # fixed Sum(a[i0,i1], i0)[1]=0 Sum(a[i0,i1], i0)[2]=0 >>> Sum(a[i0,i1], i1) # empty >>> Sum(a[i0,i1]) 0 - :#1019: PySIMPLE の mpsout が目的関数の定数項に対応していない 目的関数が定数項を含む場合,:obj:`~pysimple.Problem.mpsout` が目的関数を誤って出力する不具合を修正しました. - :#1022: 条件文の結果を間違うことがある 稀に条件文の結果を間違うことがある不具合を修正しました. [1.2.0] - 2021-03-29 -------------------- :Added: - :PYSIMPLE-135: 二次計画問題対応 制約式,目的関数に二次式を扱うことができるようになりました. - :PYSIMPLE-136: wcsp/wls 対応 重み付き制約充足問題に対するメタヒューリスティクス解法 wcsp を呼び出せるようになりました. 新たなメタヒューリスティクスアルゴリズム wls を利用できるようになりました. - :PYSIMPLE-172: Python 3.9 対応 Python 3.9 に対応しました. :Changed: - :PYSIMPLE-185: Variable/Expression.val の戻り値型の統一性 添字を持たない式に対する ``.val`` 等の属性は :obj:`~pysimple.table.Table` を返すようにしました. 以前は組込み型でした.特に目的関数が該当するので注意ください. - :PYSIMPLE-192: 変数の bound error のタイミング 変数の bound チェックを行うタイミングを求解時から宣言時にしました. ただし,:obj:`~pysimple.Variable.type` 属性を後から変更したタイミングでは bound チェックは行われません. >>> x = Variable(lb=3, ub=2, name='x') pysimple.error.SimpleError: infeasible bound of variable x ( defined infeasible bound [3 <= * <= 2] ) :Removed: - :PYSIMPLE-198: Python 3.6 サポート Python 3.6 は非対応となりました. :Fixed: - :#967: 同類項が整理されていない式の二項演算の結果を間違う 同類項が整理されていない式に対して二項演算の結果を間違う不具合を修正しました. 同類項の整理アルゴリズムの強化に加え,同類項が整理されていない場合でも問題ないアルゴリズムとしました. - :#992: setitem でエラーになることがある setitem で意図しない IndexError が発生することがある不具合を修正しました. - :PYSIMPLE-118: 条件を更に Condition で条件付けると SimpleError になる Cond 型のオブジェクトを Condition に用いると SimpleError になる不具合を修正しました. >>> i = Element(value=[0,1,2], name='i') >>> i0 = i>0 >>> Condition(i0, i0<2) ((i>0), ((i>0)<2))[(i>0)] in [1] [1.1.2] - 2020-09-11 -------------------- :Fixed: - :#954: 変数の同類項を複数含む式同士の加減でエラー 計算でエラーとなっていたものを修正しました. >>> i = Element(value=[1,2], name='i') >>> x = Variable(index=i, name='x') >>> y = Variable(index=i, name='y') >>> e = x[i] + y[i] >>> e (x[i]+y[i]): x[1]+y[1] x[2]+y[2] >>> e + e # fixed ((x[i]+y[i])[i]+(x[i]+y[i])[i]): 2*x[1]+2*y[1] 2*x[2]+2*y[2] - :#965: 上下限値や定数項に 2^31 以上の整数型を指定するとオーバーフロー 変数の上下限値や定数項に 2^31 以上の整数型を指定すると求解時に OverflowError となる不具合を修正しました. [1.1.1] - 2020-06-08 -------------------- :Added: - :#883: Collection メソッドのサポート collections.abc.Collection がサポートするメンバ __contains__, __len__, __iter__ を :obj:`~pysimple.Parameter`,:obj:`~pysimple.table.Table`, :obj:`~pysimple.Variable`,:obj:`~pysimple.expression.Expression`,:obj:`~pysimple.constraint.Constraint`, のすべてがサポートするようになりました. :Fixed: - :#933: 添字が逆転する演算を間違う ``j*x[i,j]`` のように,変数の添字に対して演算結果の添字が逆転する場合に計算結果を誤る不具合を修正しました. >>> i = Element(value='XY', name='i') >>> j = Element(value=[1, 2], name='j') >>> x = Variable(index=(i,j), name='x') >>> j*x[i,j] # Index(j,i) (j*x[i,j]): x['X',1] x['Y',1] 2*x['X',2] 2*x['Y',2] - :PYSIMPLE-181: 範囲関数の範囲重複判定の厳密化 範囲関数の範囲に同じ添字を含んでいてもスライス単位で重複していなければ許可されるようになりました. - :PYSIMPLE-184: 特定の式に対する二項演算ができない 特定の変数・式同士の二項演算ができない不具合を修正しました. [1.1.0] - 2020-03-02 -------------------- PySIMPLE 1.1.0 では式展開が劇的に高速化されました. 1.0.1 と比較して 10 倍以上の高速化を達成し,C++SIMPLE と比較しても遜色のない速度になりました. また,`Nuorium 統合環境 `_ も外部コマンドの実行に対応し, Nuorium 統合環境上で PySIMPLE が動作するようになりました.→ `how_to_solve` 動作環境も Linux,Mac がサポートされるようになり,最新の Python 3.8 にも対応しました. :Added: - :PYSIMPLE-140: Linux,Mac 版 Linux,Mac 版に対応しました. - :PYSIMPLE-158: Python 3.8 対応 Python 3.8 に対応しました. - :PYSIMPLE-157: Set のスライス :obj:`~pysimple.Set.__getitem__` の引数にスライスオブジェクトが対応しました. >>> I = Set(value=[1,2,3], name='I') >>> I Set(name='I', value=[1, 2, 3]) >>> I[:-1] Set(name='I[:-1]', value=[1, 2]) - :#839: 求解オプションの初期化 設定した求解オプションを del 文で初期値に戻すことができるようになりました. >>> p = Problem() >>> print(p.options.maxTime) None >>> p.options.maxTime = 1 >>> p.options.maxTime 1 >>> del p.options.maxTime >>> print(p.options.maxTime) None また,``del p.options`` ですべての求解オプションを初期値に戻すことができます. 詳細は :doc:`guide/options` をご確認ください. - :PYSIMPLE-80: mpsout Problem に mpsout メソッドが追加されました.詳細は :obj:`~pysimple.Problem.mpsout` をご確認ください. :Changed: - :PYSIMPLE-153: bound 周りの仕様 :obj:`~pysimple.Variable.lb`,:obj:`~pysimple.Variable.ub` 属性は immutable になり, bound 制約は制約式に一本化されました. これにより変数,制約式の dual が正しく取得できます. >>> i = Element(value=[1,2], name='i') >>> x = Variable(index=i, lb=15, name='x') >>> x.lb x[1].lb=15 x[2].lb=15 >>> p = Problem() >>> p += x[i] >= i*10, 'cons' >>> x.lb x[1].lb=15 x[2].lb=15 >>> p += Sum(x[i]) >>> p.solve(silent=True) 1 >>> x.val x[1].val=15.000000041666626 x[2].val=20.000000041666624 >>> x.dual x[1].dual=1.0 x[2].dual=0.0 >>> p['cons'].dual cons[1].dual=0.0 cons[2].dual=1.0 :Removed: - :PYSIMPLE-167: Python 3.5 サポート Python 3.5 は非対応となりました. :Fixed: - :#805: 多次元集合の一部メソッドの引数制限 実装の都合により,多次元集合に対する :obj:`~pysimple.Set.__getitem__`,:obj:`~pysimple.Set.next`, :obj:`~pysimple.Set.prev` の引数に `element-like` を禁止します. :obj:`~pysimple.Set.index` では可能です. >>> IJ = Set(value=[(1,2), (3,4), (5,6)], name='IJ') >>> i = Element(value=[0,2], name='i') >>> IJ[0] (1, 2) >>> IJ[i] TypeError: cannot apply IJ[i] to multidimensional Set >>> ij = Element(value=[(3,4)], name='ij') >>> IJ.next((3,4)) (5, 6) >>> IJ.next(ij) TypeError: cannot apply IJ.next(ij) to multidimensional Set >>> IJ.index((3,4)) 1 >>> IJ.index(ij) IJ.index(ij)[3,4]=1 - :#852: Parameter * Variable/Expression の添字順 Parameter * Variable/Expression の演算結果のインデックス順を出現順にしました. >>> i = Element(value=[1,2], name='i') >>> j = Element(value=[3,4], name='j') >>> a = Parameter(index=(i,j), name='a') >>> x = Variable(index=j, name='x') >>> a[i,j] = 10*i+j >>> ax = a[i,j]*x[j] >>> ax (a[i,j]*x[j]): 13*x[3] 14*x[4] 23*x[3] 24*x[4] >>> ax.index Index(i,j) - :PYSIMPLE-69: 目的関数の定数値の処理 目的関数に定数項が存在した場合,求解情報や :obj:`~pysimple.problem.Result.optValue` に反映されない 不具合を修正しました.:obj:`~pysimple.Problem.objective` の val 属性は今まで通り正しい値が入ります. >>> i = Element(value=[1,2]) >>> x = BinaryVariable(index=i) >>> p = Problem(type=max) >>> p += Sum(x[i]) + 10 >>> p.solve() : VALUE_OF_OBJECTIVE 12 : >>> p.result.optValue 12.0 >>> p.objective.val 12 - :PYSIMPLE-76: IPython 環境から実行した場合の出力先 求解情報がコンソールに出力される不具合を修正しました. - :PYSIMPLE-137: silent=True で主要なインタプリタから求解できない IDLE や IPython などのインタプリタ上で ``silent=True`` で求解できない不具合を修正しました. [1.0.1] - 2019-07-01 -------------------- :Fixed: - :PYSIMPLE-104: 目的関数に与えていない変数の初期値が変わる 一部を目的関数に与えた変数のうち,与えていない部分の値が変わる不具合を修正しました. >>> p = Problem() >>> i = Element(value=[1,2], name='i') >>> x = Variable(index=i, lb=1, init=2, name='x') >>> x.val x[1].val=2 x[2].val=2 >>> p += x[2] >>> p.solve(silent=True) 1 >>> x.val x[1].val=2 # 2 のままになるようにした x[2].val=1.0000000002083331 - :PYSIMPLE-117: 範囲演算における戻り値のインデックス順 範囲演算における戻り値のインデックス順を出現順にしました. >>> ij = Element(value=[(1,3), (1,4), (2,3)], name='ij') >>> i = Element(set=ij.set(0), name='i') >>> j = Element(set=ij.set(1), name='j') >>> y = Variable(index=(i,j), name='y') >>> y[i,j] = 10*i+j >>> y.val y[1,3].val=13 y[1,4].val=14 y[2,3].val=23 y[2,4].val=24 >>> Sum(y[ij(0),j], ij(0)).index Index(ij(1),j) # 以前は (j,ij(1)) だった >>> Sum(y[ij(0),j], ij(0)) Sum(y[ij(0),j], ij(0)): y[1,3]+y[2,3] y[1,4]+y[2,4] y[1,3] y[1,4] >>> Sum(y[ij(0),j], ij(0)).val Sum(y[ij(0),j], ij(0))[3,3].val=36 Sum(y[ij(0),j], ij(0))[3,4].val=38 Sum(y[ij(0),j], ij(0))[4,3].val=13 Sum(y[ij(0),j], ij(0))[4,4].val=14 - :PYSIMPLE-119: 範囲関数の範囲に空集合が含まれていたときの値 挙動を C++SIMPLE に合わせました. >>> i0 = Element(value=[], name='i0') >>> i1 = Element(value=[1], name='i1') >>> y = Variable(index=(i0,i1), name='y') >>> Sum(y[i0,i1], i0) Sum(y[i0,i1], i0): 0 >>> Sum(y[i0,i1], i1) Sum(y[i0,i1], i1): # 空の式が返るようにした >>> Sum(y[i0,i1], (i0,i1)) Sum(y[i0,i1], (i0,i1)): 0 - :PYSIMPLE-125: Parameter を含むアクセスをした式の表示 少し複雑なアクセスを含む式の表示がおかしくなる不具合を修正しました. >>> i = Element(value=[1,2,3], name='i') >>> x = Variable(index=i, name='x') >>> t = Element(value=[1,2], name='t') >>> x[t] x: x[1] x[2] >>> x[t+1] x[(t+1)[t]]: x[(t+1)[t]][1] x[(t+1)[t]][2] >>> x[t+1]+1 (x[(t+1)[t]][t]+1): x[2]+1 x[3]+1 >>> x[t] + x[t+1] (x[t]+x[(t+1)[t]][t]): x[1]+x[2] x[2]+x[3] >>> x[t+1] + x[t] (x[(t+1)[t]][t]+x[t]): x[1]+x[2] x[2]+x[3] [1.0.0] - 2019-03-08 -------------------- リリース