----
title: Common errors when evaluating IML code in ImandraX 
description: A set of common errors and recommended solutions
order: 1
----


---

## 1. monadic_binding_pattern_match  
**Kind:** TypeErr  
**Error Message:**  
> Unknown identifier `let*`.

---

### 🧪 Reproduction (IML)

```ocaml
type order_type = Market | Limit

type order = {
  order_type : order_type;
  order_price : real;
}

type order_book = {
  buy_orders : order list;
}

let next_buy (ob : order_book) : order option =
  List.nth 0 ob.buy_orders

let ob : order_book = {
  buy_orders = [{order_type = Market; order_price = 100.0}];
}

let b_bid =
  let* next = next_buy ob in
  if next.order_type <> Market then
    Some next.order_price
  else
    None
```

### 🧭 Error Location

  **Start:** line 20, col 3  
  **Stop:** line 20, col 6  

---

##### 💡 Explanation

The `let*` binding operator is not available globally in IML. It must be brought into scope by opening the appropriate module (`Option`, `Result`, etc.).

---

##### ✅ Solution

```ocaml
type order_type = Market | Limit

type order = {
  order_type : order_type;
  order_price : real;
}

type order_book = {
  buy_orders : order list;
}

let next_buy (ob : order_book) : order option =
  List.nth 0 ob.buy_orders

let ob : order_book = {
  buy_orders = [{order_type = Market; order_price = 100.0}];
}

let b_bid =
  match next_buy ob with
  | Some next ->
    if next.order_type <> Market then
      Some next.order.price
    else
      None
  | None -> None
```

**Solution Description:** Replace monadic binding with explicit pattern matching.

---

## 2. real_comparison_operators  
**ID:** `019a069f-39b7-7be1-91f6-ec2ad7c3b7ba`  
**Created at:** 2025-10-21T11:54:49.655241+00:00  
**Kind:** TypeErr  
**Error Message:**  
> Application failed: expected argument of type `int` but got `(price : real)`

---

### 🧪 Reproduction (IML)

```ocaml
let price : real = 10.5
let threshold : real = 5.0
let max_price : real = 100.0

let result =
  if price < threshold then
    Some price
  else if price > max_price then
    Some max_price
  else
    None
```

---

### 🧭 Error Location

- **File:** `<none>`  
  **Start:** line 6, col 6  
  **Stop:** line 6, col 22  

---

### 💡 Explanation

IML’s standard comparison operators (`<`, `>`, `<=`, `>=`) are typed for integers by default.  
Using them on real numbers causes a type error. The `Real` module provides separate comparison operators for real numbers.

---

### ✅ Solution

```ocaml
let price : real = 10.5
let threshold : real = 5.0
let max_price : real = 100.0

let result =
  if Real.(<) price threshold then
    Some price
  else if Real.(>) price max_price then
    Some max_price
  else
    None
```

**Solution Description:**  
Use `Real` module comparison operators: `Real.(<)`, `Real.(>)`, `Real.(<=)`, `Real.(>=)`.

---

## 3. termination_measure_annotation  
**Kind:** TacticEvalErr  
**Error Message:**  
> Tactic failed: Goal is counter-satisfiable.

---

### 🧪 Reproduction (IML)

```ocaml
let rec left_pad c n xs =
  if List.length xs >= n then
    xs
  else
    left_pad c n (c :: xs)
```

---

### 💡 Explanation

IML cannot automatically prove termination when the recursion pattern is non-standard  
(e.g., recursion on list length rather than list structure).  
An explicit **measure annotation** is required to show what decreases with each recursive call.

---

### ✅ Solution

```ocaml
let left_pad_measure n xs =
  Ordinal.of_int (n - List.length xs)

let rec left_pad c n xs =
  if List.length xs >= n then
    xs
  else
    left_pad c n (c :: xs)
[@@measure left_pad_measure n xs]
```

**Solution Description:**  
Add `[@@measure ...]` annotation with a function returning `Ordinal.t`  
that provably decreases on each recursive call.

