﻿P := plan {
  param Widgets := [
    { Id: 0, Value:  2, Cost:  3 },
    { Id: 1, Value:  8, Cost:  5 },
    { Id: 2, Value:  7, Cost:  3 },
    { Id: 3, Value:  6, Cost:  2 },
    { Id: 4, Value:  9, Cost:  7 },
    { Id: 5, Value:  8, Cost:  7 },
  ];
  param Gizmos := [
    { Id: 0, Value:  2, Cost:  3 },
    { Id: 1, Value:  8, Cost:  5 },
    { Id: 2, Value:  7, Cost:  4 },
  ];

  param ValPerCost := 1.0;
  param MinValue := 10;
  param MaxCost  := 19;

  // Need one of each.
  var Widget in Widgets req;
  var Gizmo  in Gizmos  req;

  msr Value := Widget.Value + Gizmo.Value;
  msr Cost  := Widget.Cost  + Gizmo.Cost;
  msr Score := Value - ValPerCost * Cost;

  con Cons := [ Value >= MinValue, Cost <= MaxCost ];
};

P->Maximize(Value, "GLPK");
P->Maximize(Value, "HiGHS");
P->Maximize(Value, "Gurobi"); // Should fail.
P->Minimize(Cost , "Glpk");
P->Minimize(Cost , "Highs");
P->Maximize(Score, "glpk");
P->Maximize(Score, "highs");
P with { ValPerCost: 0.5, MaxCost: 100000000000, MinValue: 0 }->Maximize(Score);

P := plan {
  param Vs := Range(5);
  var X in Vs required;
  var Y in Vs optional;
  msr MX := X;
  msr MY := Y;
};

P->Maximize(MX);
P->Maximize(MY); // Not linear.
