# Retrieving solution status and values¶

## Status of the solution¶

A feasible solution is an assignment of values to decisions variables such that:

• all constraints are satisfied

• no objective has undefined value. Undefined values can occur when performing illegal mathematical operations (square root of negative number for instance) or accessing outside the bounds of an array.

Note that some values can be undefined in a feasible solution, provided that all objectives have valid values. For instance a conditional expression `x > 0 ? sqrt(x) : sqrt(-x)` always has one of its branches undefined, but its output is always valid.

At the end of the search, the status of the solution can be one of the following:

• `INCONSISTENT` if the solver was able to prove that no feasible solution can be found

• `INFEASIBLE` if no feasible solution has been found yet

• `FEASIBLE` if a feasible solution has been computed

• `OPTIMAL` if a feasible solution has been found whose optimality has been proven (objective value within 0.01% of computed bound for each objective).

This status can be retrieved at any time after the model has been closed.

```// it allows you to access to the current solution, for instance in the output() function
function output() {

println("Status is " + getSolutionStatus());

// you can also compare the status to its possible values
if (getSolutionStatus() == 0) ...
else if (getSolutionStatus() == 1) ...
else if (getSolutionStatus() == 2) ...
else if (getSolutionStatus() == 3) ...
}
```
```# with ls an object of type LocalSolver

print("Status is " + ls.solution.status)

# you can also compare the status to its possible values
if ls.solution.status == LSSolutionStatus.INCONSISTENT:
...
elif ls.solution.status == LSSolutionStatus.INFEASIBLE:
...
elif ls.solution.status == LSSolutionStatus.FEASIBLE:
...
elif ls.solution.status == LSSolutionStatus.OPTIMAL:
...
```
```// with ls an object of type LocalSolver

std::cout << "Status is " << ls.getSolution().getStatus() << std::endl;

// you can also compare the status to its possible values
if (ls.getSolution().getStatus() == SS_INCONSISTENT) ...
else if (ls.getSolution().getStatus() == SS_INFEASIBLE) ...
else if (ls.getSolution().getStatus() == SS_FEASIBLE) ...
else if (ls.getSolution().getStatus() == SS_OPTIMAL) ...
```
```// with ls an object of type LocalSolver

Console.Writeline("Status is " + ls.GetSolution().GetStatus());

// you can also compare the status to its possible values
if (ls.GetSolution().GetStatus() == SolutionStatus.Inconsistent) ...
else if (ls.GetSolution().GetStatus() == SolutionStatus.Infeasible) ...
else if (ls.GetSolution().GetStatus() == SolutionStatus.Feasible) ...
else if (ls.GetSolution().GetStatus() == SolutionStatus.Optimal) ...
```
```// with ls an object of type LocalSolver

System.out.println("Status is " + ls.getSolution().getStatus());

// you can also compare the status to its possible values
if (ls.getSolution().getStatus() == SolutionStatus.Inconsistent) ...
else if (ls.getSolution().getStatus() == SolutionStatus.Infeasible) ...
else if (ls.getSolution().getStatus() == SolutionStatus.Feasible) ...
else if (ls.getSolution().getStatus() == SolutionStatus.Optimal) ...
```

## Values of numeric variables and expressions¶

Numeric variables and expressions are expressions of the mathematical model whose value is a boolean and integer of a floating point number. Three methods are available on expressions to identify these expressions: `isBool()`, `isInt()` and `isDouble()` (or in Python `is_bool`, `is_int` and `is_double` and in C# `IsBool()`, `IsInt()` and `IsDouble()`).

As mentioned above, an expression can have an undefined value, what can be detected with function `is_undefined` (Python), `isUndefined` (LSP/Java/C++) or `IsUndefined` (C#).

```function output() {
// with x an ls expression
if (x.isUndefined()) throw "X was expected to have a valid value";
println("x is boolean" ? + (x.isBool() ? "YES": "NO"));
println("value of x is "+ x.value);
}
```
```# with x an object of type LSExpression
if x.is_undefined():
raise Exception("X was expected to have a valid value")
print("x is boolean ? " + ("YES" if x.is_bool() else "NO"))
print("value of x is " + x.value)
```
```// with x an object of type LSExpression
if (x.isUndefined()) throw "X was expected to have a valid value";
std::cout << "x is boolean ? "<< (x.isBool() ? "YES" : "NO") << std::endl;
// same method to retrieve int and bool values
std::cout << "value of x is "<< (x.isDouble() ? x.getDoubleValue() : x.getIntValue() << std::endl;
```
```// with x an object of type LSExpression
if (x.IsUndefined()) throw new Exception("X was expected to have a valid value");
Console.Writeline("x is boolean ? " + (x.isBool() ? "YES": "NO"));
// same method to retrieve int and bool values
Console.Writeline("value of x is " + (x.IsDouble() ? x.GetDoubleValue() : x.GetIntValue());
```
```// with x an object of type LSExpression
if (x.isUndefined()) throw new Exception("X was expected to have a valid value");
System.out.println("x is boolean ? " + (x.isBool() ? "YES": "NO"));
// same method to retrieve int and bool values
System.out.println("value of x is " + (x.isDouble() ? x.getDoubleValue() : x.getIntValue());
```

## Values of collection variables and expressions¶

Some expressions of a LocalSolver model do not take numeric values. For instance the value of a set or a list is a collection of integers. Similarly the value of an array expression is an array of values.

Generally, collections or arrays are clearly identified by the user. If needed the necessary methods are available on LSExpression objects to check this value type. The values of these expressions are of type LSCollection (for set and list) or LSArray (for arrays).

These types can be printed directly (the output is formatted with brackets e.g. [4, 8, 7, 2]) or the user can retrieve its values one by one.

```function output() {
// with mycoll a set or list expression
local coll = mycoll.value;
println("Collection values = " + coll);
println("Collection size = " + coll.count);
// note that indexing starts at 0 and that the values of a set
// are given in increasing order
println("Collection 8th value = " + coll);

// with myarray an array expression
local arrayvals = myarray.value;
println("Array value = " + arrayvals);
println("Array size = " + arrayvals.count);
println("Array 8th value = " + arrayvals));
}
```
```# with mycoll a set or list expression
coll = mycoll.value
print("Collection values = " + coll)
print("Collection size = " + coll.count())
# note that indexing starts at 0 and that the values of a set
# are given in increasing order
print("Collection 8th value = " + coll)

# with myarray an array expression
arrayvals = myarray.value
print("Array value = " + arrayvals)
print("Array size = " + arrayvals.count())
print("Array 8th value is double = " + arrayvals.is_double(7))
print("Array 8th value = " + arrayvals)
```
```// with mycoll a set or list expression
LSCollection coll = mycoll.getCollectionValue();
std::cout << Collection values = " << coll.toString() << std::endl;
std::cout << "Collection size = " << coll.count() << std::endl;
// note that indexing starts at 0 and that the values of a set
// are given in increasing order
std::cout << "Collection 8th value = " << coll << std::endl;

// with myarray an array expression
LSArray arrayvals = myarray.getArrayValue();
std::cout << "Array value = " << arrayvals.toString() << std::endl;
std::cout << "Array size = " << arrayvals.count() << std::endl;
std::cout << "Array 8th value is double = " << arrayvals.isDouble(7) << std::endl;
std::cout << "Array 8th value = " << arrayvals << std::endl;
```
```// with mycoll a set or list expression
LSCollection coll = mycoll.GetCollectionValue();
Console.Writeline("Collection values = " + coll);
Console.Writeline("Collection size = " + coll.Count());
// note that indexing starts at 0 and that the values of a set
// are given in increasing order
Console.Writeline("Collection 8th value = " + coll);

// with myarray an array expression
LSArray arrayvals = myarray.GetArrayValue();
Console.Writeline("Array value = " + arrayvals);
Console.Writeline("Array size = " + arrayvals.Count());
Console.Writeline("Array 8th value is double = " + arrayvals.IsDouble(7));
Console.Writeline("Array 8th value = " + arrayvals);
```
```// with mycoll a set or list expression
LSCollection coll = mycoll.getCollectionValue();
System.out.println("Collection values = " + coll);
System.out.println("Collection size = " + coll.count());
// note that indexing starts at 0 and that the values of a set
// are given in increasing order
System.out.println("Collection 8th value = " + coll.get(7));

LSArray arrayvals = arr.getArrayValue();
System.out.println("Array value = " + arrayvals);
System.out.println("Array size = " + arrayvals.count());
System.out.println("Array 8th value is double = " + arrayvals.isDouble(7));
System.out.println("Array 8th value = " + arrayvals.getDoubleValue(7));
```