# How to Enable and Configure Debug Logging Using the curryhoward.log JVM Property

> Easily enable and configure debug logging for the CurryHoward library. Set the curryhoward.log JVM property with specific options like prover, trace, and macros for detailed output.

- Repository: [Chymyst/curryhoward](https://github.com/chymyst/curryhoward)
- Tags: how-to-guide
- Published: 2026-02-27

---

**Set the JVM system property `curryhoward.log` to a comma-separated list of options (`prover`, `trace`, `macros`, `verbose`, `terms`) to activate specific debug output channels in the CurryHoward library.**

The `chymyst/curryhoward` library uses a centralized logging mechanism controlled entirely by the `curryhoward.log` JVM property. When you enable and configure debug logging using the `curryhoward.log` JVM property, the library parses the value at runtime in [`src/main/scala/io/chymyst/ch/Macros.scala`](https://github.com/chymyst/curryhoward/blob/main/src/main/scala/io/chymyst/ch/Macros.scala) and activates targeted diagnostic output for theorem proving, macro expansion, and term generation.

## Understanding the curryhoward.log JVM Property

The property acts as a comma-delimited flag parser. In [`Macros.scala`](https://github.com/chymyst/curryhoward/blob/main/Macros.scala) (lines 497–503), the private `options` method reads the system property, splits it on commas, and converts the tokens to a `Set[String]`:

```scala
private[ch] def options: Set[String] = 
  Option(System.getProperty("curryhoward.log")).getOrElse("")
        .split(",")
        .toSet

```

Each token in the set toggles a specific boolean debug flag elsewhere in the codebase. If the property is undefined, the set is empty and all debug output remains silent.

## Available Debug Options

The library recognizes five distinct logging tokens. Each maps to a specific boolean value that guards `println` or `c.info` statements.

### prover

Enables `TheoremProver.debug` (line 9 of [`TheoremProver.scala`](https://github.com/chymyst/curryhoward/blob/main/TheoremProver.scala)). When active, the theorem-prover engine emits detailed proof-search diagnostics, including sequent transformations and final proof term counts.

### trace

Activates `TheoremProver.debugTrace` (line 11 of [`TheoremProver.scala`](https://github.com/chymyst/curryhoward/blob/main/TheoremProver.scala)). This option adds timing data and intermediate sequent snapshots to the prover output, useful for performance analysis.

### macros

Controls `Macros.debug` (line 42 of [`Macros.scala`](https://github.com/chymyst/curryhoward/blob/main/Macros.scala)). This flag prints debug messages during macro expansion, showing how the library translates Scala types into logical propositions.

### verbose

Drives `Macros.verbose` (line 44 of [`Macros.scala`](https://github.com/chymyst/curryhoward/blob/main/Macros.scala)). A more detailed variant of `macros`, this outputs additional internal state during macro processing.

### terms

Toggles `Macros.showReturningTerm` (line 46 of [`Macros.scala`](https://github.com/chymyst/curryhoward/blob/main/Macros.scala)). When enabled, the macro prints the generated lambda term before returning it to the compiler, letting you inspect the synthesized code.

## How to Set the curryhoward.log Property

You can configure the property either via the JVM command line or programmatically within your Scala application.

### Command-Line Configuration with sbt

Pass the property to the JVM through sbt’s `-D` flag. For example, to enable prover debug output during a specific test:

```bash
sbt "testOnly io.chymyst.ch.unit.MiscSpec -- -Dcurryhoward.log=prover"

```

To combine multiple options, separate them with commas (no spaces):

```bash
sbt -Dcurryhoward.log=macros,terms run

```

For full trace output alongside prover diagnostics:

```bash
sbt -Dcurryhoward.log=prover,trace test

```

### Programmatic Configuration in Scala

You can also set the property from within your code, which is useful in test suites or REPL sessions. The test suite in [`MiscSpec.scala`](https://github.com/chymyst/curryhoward/blob/main/MiscSpec.scala) (lines 54–66) demonstrates this pattern:

```scala
// Enable debug logging before invoking macros
System.setProperty("curryhoward.log", "macros,terms")

// ... invoke CurryHoward macros ...

// Clean up after the test
System.clearProperty("curryhoward.log")

```

Similarly, [`LJTSpec3.scala`](https://github.com/chymyst/curryhoward/blob/main/LJTSpec3.scala) (lines 34–36) shows combined usage:

```scala
System.setProperty("curryhoward.log", "prover,macros,terms,trace")

```

## Summary

- The `curryhoward.log` JVM property accepts a comma-separated list of debug tokens parsed in [`Macros.scala`](https://github.com/chymyst/curryhoward/blob/main/Macros.scala).
- **Five options** control output: `prover` and `trace` for theorem-prover diagnostics ([`TheoremProver.scala`](https://github.com/chymyst/curryhoward/blob/main/TheoremProver.scala)), and `macros`, `verbose`, and `terms` for macro expansion details ([`Macros.scala`](https://github.com/chymyst/curryhoward/blob/main/Macros.scala)).
- Configure the property via **sbt command line** (`-Dcurryhoward.log=option1,option2`) or **programmatically** using `System.setProperty`.

## Frequently Asked Questions

### What happens if I set an unsupported option in curryhoward.log?

The library silently ignores any token that does not match the known set. The `options` method in [`Macros.scala`](https://github.com/chymyst/curryhoward/blob/main/Macros.scala) simply converts the split strings to a `Set[String]`; downstream checks look for specific keys, so unknown values have no effect and produce no warnings.

### Can I enable all debug output at once?

There is no single "all" token. To capture every diagnostic channel, you must explicitly list all five options: `prover,trace,macros,verbose,terms`. For example: `sbt -Dcurryhoward.log=prover,trace,macros,verbose,terms test`.

### Does the curryhoward.log property affect runtime performance?

Yes, but only when specific options are active. The library guards expensive debug logic with boolean checks (e.g., `if (TheoremProver.debug) ...`). When the property is unset or empty, these booleans are `false` and the compiler optimizes away the debug code paths, resulting in zero overhead.

### Where can I see examples of debug logging in the test suite?

The test files [`MiscSpec.scala`](https://github.com/chymyst/curryhoward/blob/main/MiscSpec.scala) and [`LJTSpec3.scala`](https://github.com/chymyst/curryhoward/blob/main/LJTSpec3.scala) demonstrate programmatic configuration. [`MiscSpec.scala`](https://github.com/chymyst/curryhoward/blob/main/MiscSpec.scala) (lines 54–66) shows setting and clearing the property around a test case, while [`LJTSpec3.scala`](https://github.com/chymyst/curryhoward/blob/main/LJTSpec3.scala) (lines 34–36) enables multiple options before running theorem-prover tests.