diff --git a/debug.md b/debug.md new file mode 100644 index 0000000..4d5fcfb --- /dev/null +++ b/debug.md @@ -0,0 +1,8 @@ +i have a compiler Im writing in elixir. I need to trace execution of logic to pinpoint bugs. +I have many tests I want to debug individually but I can run only the full test suite. +I want to create a couple of macros/functions that'd enable me to debug my code. +the scenario I imagine: +before the test I want to debug I write `Tdd.Debug.enable` +And after the test line I add `Tdd.Debug.print_and_disable`. +The last line prints a tree of called functions, their arguments and return values. +We can modify compiler functions. diff --git a/new.exs b/new.exs index 0be7449..1c7c9c1 100644 --- a/new.exs +++ b/new.exs @@ -3052,7 +3052,7 @@ defmodule TddCompilerRecursiveTests do end end end - +Process.sleep(100) # To run this new test, add the following to your main test runner script: # TddCompilerRecursiveTests.run() TypeSpecTests.run() diff --git a/output.md b/output.md new file mode 100644 index 0000000..7b8184f --- /dev/null +++ b/output.md @@ -0,0 +1,243 @@ + +--- Running Tdd.TypeSpec.normalize/1 Tests --- + +--- Section: Base & Simple Types --- +[PASS] Normalizing :any is idempotent +[PASS] Normalizing :none is idempotent +[PASS] Normalizing :atom is idempotent +[PASS] Normalizing a literal is idempotent + +--- Section: Double Negation --- +[PASS] ¬(¬atom) simplifies to atom +[PASS] A single negation is preserved +[PASS] ¬(¬(¬atom)) simplifies to ¬atom + +--- Section: Union Normalization --- +[PASS] Flattens nested unions +[PASS] Sorts members of a union +[PASS] Removes duplicates in a union +[PASS] Simplifies a union with :none (A | none -> A) +[PASS] Simplifies a union with :any (A | any -> any) +[PASS] An empty union simplifies to :none +[PASS] A union containing only :none simplifies to :none +[PASS] A union of a single element simplifies to the element itself + +--- Section: Intersection Normalization --- +[PASS] Flattens nested intersections +[PASS] Sorts members of an intersection +[PASS] Removes duplicates in an intersection +[PASS] Simplifies an intersection with :any (A & any -> A) +[PASS] Simplifies an intersection with :none (A & none -> none) +[PASS] An empty intersection simplifies to :any +[PASS] An intersection of a single element simplifies to the element itself + +--- Section: Recursive Normalization --- +[PASS] Recursively normalizes elements in a tuple +[PASS] Recursively normalizes head and tail in a cons +[PASS] Recursively normalizes element in list_of +[PASS] Recursively normalizes sub-spec in negation + +--- Section: Complex Nested Cases --- +[PASS] Handles complex nested simplifications correctly + +✅ All TypeSpec tests passed! + +--- Running Tdd.Store Tests --- + +--- Section: Initialization and Terminals --- +[PASS] true_node_id returns 1 +[PASS] false_node_id returns 0 +[PASS] get_node for ID 1 returns true_terminal +[PASS] get_node for ID 0 returns false_terminal +[PASS] get_node for unknown ID returns not_found + +--- Section: Node Creation and Structural Sharing --- +[PASS] First created node gets ID 2 +[PASS] get_node for ID 2 returns the correct tuple +[PASS] Second created node gets ID 3 +[PASS] Attempting to create an existing node returns the same ID (Structural Sharing) +[PASS] Next new node gets the correct ID (4) + +--- Section: Basic Reduction Rule --- +[PASS] A node with identical children reduces to the child's ID + +--- Section: Caching --- +[PASS] Cache is initially empty for a key +[PASS] Cache returns the stored value after put +[PASS] Cache can be updated + +✅ All Tdd.Store tests passed! + +--- Running Tdd.Variable Tests --- + +--- Section: Variable Structure --- +[PASS] v_is_atom returns correct tuple +[PASS] v_atom_eq returns correct tuple +[PASS] v_int_lt returns correct tuple +[PASS] v_tuple_size_eq returns correct tuple +[PASS] v_tuple_elem_pred nests a variable correctly +[PASS] v_list_is_empty returns correct tuple +[PASS] v_list_head_pred nests a variable correctly + +--- Section: Global Ordering (Based on Elixir Term Comparison) --- +[PASS] Primary type var < Atom property var +[PASS] Integer :lt var < Integer :eq var +[PASS] Integer :eq var < Integer :gt var +[PASS] Integer :eq(5) var < Integer :eq(10) var +[PASS] Tuple elem(0) var < Tuple elem(1) var +[PASS] Tuple elem(0, atom) var < Tuple elem(0, int) var +Variable.v_list_is_empty(): {5, :b_is_empty, nil, nil} +[PASS] List :b_is_empty var < List :c_head var +[PASS] List :c_head var < List :tail var + +✅ All Tdd.Variable tests passed! + +--- Running Tdd.Algo & Tdd.Consistency.Engine Tests --- + +--- Section: Algo.negate --- +[PASS] negate(true) is false +[PASS] negate(false) is true +[PASS] negate(negate(t_atom)) is t_atom + +--- Section: Algo.apply (raw structural operations) --- +[PASS] Structure of 'atom | int' is correct +[PASS] :foo & :bar (raw) is not the false node + +--- Section: Algo.simplify (with Consistency.Engine) --- +[PASS] Simplifying under contradictory assumptions (atom & int) results in false +[PASS] Simplifying 'integer' given 'value==:foo' results in false +[PASS] Simplifying 'atom & int' results in false +[PASS] Simplifying 'atom | int' given 'is_atom==true' results in true +[PASS] Simplifying 'atom | int' given 'is_atom==false' results in 'integer' + +✅ All Tdd.Algo tests passed! + +--- Running Tdd.Consistency.Engine Tests --- + +--- Section: Basic & Implication Tests --- +[PASS] An empty assumption map is consistent +[PASS] A single valid assumption is consistent +[PASS] An implied contradiction is caught by expander +[PASS] An implied contradiction is caught by expander +[PASS] Implication creates a consistent set + +--- Section: Primary Type Exclusivity --- +[PASS] Two primary types cannot both be true +[PASS] Two primary types implied to be true is a contradiction +[PASS] One primary type true and another false is consistent + +--- Section: Atom Consistency --- +[PASS] An atom cannot equal two different values +[PASS] An atom can equal one value + +--- Section: List Flat Consistency --- +[PASS] A list cannot be empty and have a head property +[PASS] A non-empty list can have a head property +[PASS] A non-empty list is implied by head property + +--- Section: Integer Consistency --- +[PASS] int == 5 is consistent +[PASS] int == 5 AND int == 10 is a contradiction +[PASS] int < 10 AND int > 20 is a contradiction +[PASS] int > 5 AND int < 4 is a contradiction +[PASS] int > 5 AND int < 7 is consistent +[PASS] int == 5 AND int < 3 is a contradiction +[PASS] int == 5 AND int > 10 is a contradiction +[PASS] int == 5 AND int > 3 is consistent + +✅ All Consistency.Engine tests passed! + +--- Running Tdd.TypeReconstructor Tests --- + +--- Section: Basic Flat Reconstructions --- +[PASS] is_atom=true -> atom +[PASS] is_atom=false -> ¬atom +[PASS] is_atom=true AND value==:foo -> :foo +[PASS] is_atom=true AND value!=:foo -> atom & ¬:foo +[PASS] is_integer=true AND int==5 -> 5 +[PASS] is_list=true AND is_empty=true -> [] + +--- Section: Combined Flat Reconstructions --- +[PASS] int > 10 AND int < 20 + +--- Section: Recursive Reconstructions --- +[PASS] head is an atom + +✅ All TypeReconstructor tests passed! + +--- Running Compiler & Algo Integration Tests --- + +--- Section: Basic Equivalences --- +[PASS] atom & any == atom +[PASS] atom | none == atom +[PASS] atom & int == none +[PASS] ¬(¬atom) == atom +[PASS] atom | atom == atom + +--- Section: Basic Subtyping --- +[PASS] :foo <: atom +[PASS] atom <: :foo +[PASS] :foo <: integer +[PASS] int==5 <: integer +[PASS] none <: atom +[PASS] atom <: any + +--- Section: Integer Range Logic --- +[PASS] range(7..8) <: range(5..10) +[PASS] range(5..10) <: range(7..8) +[PASS] range(5..10) <: range(15..20) +[PASS] range(5..10) & range(7..8) == range(7..8) +[PASS] range(5..10) & range(0..100) == range(5..10) +[PASS] range(5..10) | range(7..8) == range(5..10) + +--- Section: Contradictions & Simplifications --- +[PASS] atom & integer +[PASS] :foo & :bar +[PASS] atom & (int==5) +[PASS] range(5..10) & range(15..20) +[PASS] integer & ¬integer + +--- Section: Subtype Reduction Logic --- +[PASS] (:foo | :bar | atom) simplifies to atom +[PASS] (range(5..10) | integer) simplifies to integer +[PASS] (:foo & atom) simplifies to :foo +[PASS] (range(5..10) & integer) simplifies to range(5..10) + +--- Section: Logical Laws --- +[PASS] De Morgan's (¬(A|B) == ¬A & ¬B) holds +[PASS] De Morgan's (¬(A&B) == ¬A | ¬B) holds +[PASS] Distributive Law (A & (B|C)) holds + +✅ All Compiler & Algo Integration tests passed! + +--- Running Tdd.Compiler Recursive Type Tests --- + +--- Section: :cons --- +[PASS] :cons is a subtype of :list +[PASS] :cons is not a subtype of the empty list +[PASS] cons(integer, list) is a subtype of cons(any, any) +[PASS] cons(any, any) is not a subtype of cons(integer, list) + +--- Section: :tuple --- +[PASS] {:tuple, [atom, int]} is a subtype of :tuple +[PASS] {:tuple, [atom, int]} is not a subtype of :list +[PASS] a tuple of size 2 is not a subtype of a tuple of size 3 +[PASS] subtype check works element-wise (specific <: general) +[PASS] subtype check works element-wise (general