Reader monad - #1062
Draft
ArkadySkv wants to merge 1 commit into
Draft
Conversation
…onad - Replace global mutable references (next, brk, covered_labels, scopes) with local state captured in a Reader monad environment. - Introduce Reader module with explicit state accessors (get_next, incr_next, update_scopes, etc.). - Refactor symbol_* and alloc functions to use Reader monad for state management. - Keep coverage and scope functions in Concrete_choice monad (FFI constraints). - Preserve replay functionality; tested with model.json replay. - Eliminates all global mutable state, improving testability and maintainability. This approach follows the Reader monad pattern requested in Issue OCamlPro#685.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refactor
cmd_replay.ml: eliminate global mutable state using Reader monadOCaml Version
mainbranch)Two Approaches Explored
1. Hybrid Approach (Closure-based local state)
Description:
next,brk,covered_labels,scopes) to the local scope ofcompile_file.Pros:
Cons:
Status: ✅ Tested and working, but abandoned in favor of a more principled approach.
2. Reader Monad + Local State (Final Approach)
Description:
Readermodule with:type 'a t = env -> 'a Result.treturn,bind,run,askget_next,incr_next,get_brk,set_brk,update_scopes, etc.symbol_*andallocfunctions in the Reader monad.cov_label_*and scope functions inConcrete_choicemonad (required by FFI interface).envrecord holds all mutable state and is passed explicitly through the monad.Pros:
Cons:
bindcalls).Status: ✅ Tested and working. Replay functionality remains intact.
🔬 Comparison of Approaches
envrecord)ReadermoduleConclusion: The Reader monad approach is more principled, explicitly manages state, and fully addresses the issue's request. Although slightly more verbose, it improves testability and maintainability, making it the preferred solution.
🧪 Testing
Test File: test.wat
Step 1: Generate the Model File
Run symbolic execution to produce a model file that captures the concrete value leading to the trap:
This command explores the symbolic path where x == 0, causing unreachable, and saves the concrete value 0 for symbol_0 in model.json.
Step 2: Replay the Model
Replay the concrete execution using the generated model:
Expected Output
This PR Closes #685
What This Proves
The replay command correctly reproduces the exact concrete path (and the trap) that was discovered during symbolic execution.
The refactoring (eliminating global mutable state and introducing the Reader monad) did not break replay functionality.
The model file (model.json) is correctly parsed and applied by the replay command.