Compare commits
No commits in common. "5bf920da3ae7e5f76a8008f3487ef8a04be9c5b9" and "de167ff5f36f3c177f42acc96b54f37c3ce1bb3b" have entirely different histories.
5bf920da3a
...
de167ff5f3
@ -57232,209 +57232,3 @@ This approach leverages the excellent foundation you've already built in the `ti
|
|||||||
> Model: openrouter/google/gemini-2.5-pro-preview with context edit format
|
> Model: openrouter/google/gemini-2.5-pro-preview with context edit format
|
||||||
> Git repo: .git with 62 files
|
> Git repo: .git with 62 files
|
||||||
> Repo-map: using 8192 tokens, always refresh
|
> Repo-map: using 8192 tokens, always refresh
|
||||||
>
|
|
||||||
>
|
|
||||||
> ^C again to exit
|
|
||||||
> Unable to list files in git repo: BadObject: b'df8d705509adca9e964524519a1755d8a584e262'
|
|
||||||
> Is your git repo corrupted?
|
|
||||||
>
|
|
||||||
>
|
|
||||||
> ^C KeyboardInterrupt
|
|
||||||
|
|
||||||
# aider chat started at 2025-06-16 11:51:46
|
|
||||||
|
|
||||||
> You can skip this check with --no-gitignore
|
|
||||||
> Add .aider* to .gitignore (recommended)? (Y)es/(N)o [Yes]: n
|
|
||||||
> /Users/kacper.marzecki@schibsted.com/.local/bin/aider --model gemini --watch-files --read Conventions.md --thinking-tokens 10k --reasoning-effort high
|
|
||||||
> Warning: gemini/gemini-2.5-pro-preview-05-06 does not support 'reasoning_effort', ignoring.
|
|
||||||
> Use --no-check-model-accepts-settings to force the 'reasoning_effort' setting.
|
|
||||||
> Warning: gemini/gemini-2.5-pro-preview-05-06 does not support 'thinking_tokens', ignoring.
|
|
||||||
> Use --no-check-model-accepts-settings to force the 'thinking_tokens' setting.
|
|
||||||
> Aider v0.84.0
|
|
||||||
> Main model: gemini/gemini-2.5-pro-preview-05-06 with diff-fenced edit format
|
|
||||||
> Weak model: gemini/gemini-2.5-flash-preview-04-17
|
|
||||||
> Git repo: .git with 65 files
|
|
||||||
> Repo-map: using 4096 tokens, auto refresh
|
|
||||||
> Added Conventions.md to the chat (read-only).
|
|
||||||
> Added test.exs to the chat
|
|
||||||
> Processing your request...
|
|
||||||
|
|
||||||
Okay, I will add the test case as requested. This involves defining a couple of helper functions to construct TDDs for tuples with specific element types, as this functionality doesn't appear to be available as a built-in constructor. These helpers will use existing TDD primitives.
|
|
||||||
|
|
||||||
Here's the plan:
|
|
||||||
1. Define two helper functions:
|
|
||||||
* `build_tuple_element_tdd_h(element_index, element_type_id, success_path_id)`: Recursively builds the TDD part for a single element by adapting the element's type TDD variables to be specific to that element's index.
|
|
||||||
* `create_specific_tuple_type_h(element_type_ids)`: Uses `build_tuple_element_tdd_h` to construct the full TDD for a tuple with a list of specified element types.
|
|
||||||
2. Use these helpers to create the TDDs for `{1, :foo}` and `{int_gt_0, :foo | :bar}`.
|
|
||||||
3. Add the subtyping test using the existing `test` function.
|
|
||||||
4. This new code will replace the `#AI! ...` comment at the end of the file.
|
|
||||||
|
|
||||||
Here are the *SEARCH/REPLACE* blocks:
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
test.exs
|
|
||||||
<<<<<<< SEARCH
|
|
||||||
|> Tdd.print_tdd(asd)
|
|
||||||
|
|
||||||
|
|
||||||
#AI! lets add a test case for {1, :foo} <: {int_gt_0, :foo | :bar}
|
|
||||||
=======
|
|
||||||
|> Tdd.print_tdd(asd)
|
|
||||||
|
|
||||||
# Helper function to recursively build TDD for an element's type,
|
|
||||||
# adapting its variables to be specific to the element's index.
|
|
||||||
defmodule TupleTestHelpers do
|
|
||||||
def build_tuple_element_tdd_h(_element_index, element_type_id, success_path_id, _variable_prefix_module)
|
|
||||||
when element_type_id == Tdd.type_any() do
|
|
||||||
# If element type is 'any', this part of the check passes, go to success_path_id
|
|
||||||
success_path_id
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_tuple_element_tdd_h(_element_index, element_type_id, _success_path_id, _variable_prefix_module)
|
|
||||||
when element_type_id == Tdd.type_none() do
|
|
||||||
# If element type is 'none', this path fails
|
|
||||||
Tdd.type_none()
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_tuple_element_tdd_h(element_index, element_type_id, success_path_id, variable_prefix_module) do
|
|
||||||
node_details = Tdd.get_node_details(element_type_id)
|
|
||||||
|
|
||||||
case node_details do
|
|
||||||
:true_terminal ->
|
|
||||||
# Should be caught by guard Tdd.type_any(), but handle defensively
|
|
||||||
success_path_id
|
|
||||||
|
|
||||||
:false_terminal ->
|
|
||||||
# Should be caught by guard Tdd.type_none(), but handle defensively
|
|
||||||
Tdd.type_none()
|
|
||||||
|
|
||||||
{original_var, y_id, n_id, d_id} ->
|
|
||||||
# Adapt original_var to be specific to this element_index
|
|
||||||
# The Tdd.v_tuple_elem_pred function creates the correctly prefixed variable
|
|
||||||
element_specific_var = variable_prefix_module.v_tuple_elem_pred(element_index, original_var)
|
|
||||||
|
|
||||||
yes_branch_tdd =
|
|
||||||
build_tuple_element_tdd_h(element_index, y_id, success_path_id, variable_prefix_module)
|
|
||||||
|
|
||||||
no_branch_tdd =
|
|
||||||
build_tuple_element_tdd_h(element_index, n_id, success_path_id, variable_prefix_module)
|
|
||||||
|
|
||||||
dc_branch_tdd =
|
|
||||||
build_tuple_element_tdd_h(element_index, d_id, success_path_id, variable_prefix_module)
|
|
||||||
|
|
||||||
Tdd.make_node_raw(element_specific_var, yes_branch_tdd, no_branch_tdd, dc_branch_tdd)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Helper function to create a TDD for a tuple with specific element types
|
|
||||||
def create_specific_tuple_type_h(element_type_ids, variable_prefix_module \\ Tdd) do
|
|
||||||
num_elements = length(element_type_ids)
|
|
||||||
|
|
||||||
# Build TDD for element checks from last to first
|
|
||||||
# The 'success_path_id' for the last element's check is Tdd.type_any() (representing TRUE)
|
|
||||||
final_elements_check_tdd =
|
|
||||||
Enum.reduce(Enum.reverse(0..(num_elements - 1)), Tdd.type_any(), fn i, acc_tdd ->
|
|
||||||
element_type_id = Enum.at(element_type_ids, i)
|
|
||||||
build_tuple_element_tdd_h(i, element_type_id, acc_tdd, variable_prefix_module)
|
|
||||||
end)
|
|
||||||
|
|
||||||
# Wrap with size check
|
|
||||||
size_check_node =
|
|
||||||
Tdd.make_node_raw(
|
|
||||||
variable_prefix_module.v_tuple_size_eq(num_elements),
|
|
||||||
final_elements_check_tdd, # If size matches, proceed to element checks
|
|
||||||
Tdd.type_none(), # If size mismatches, it's not this tuple type
|
|
||||||
Tdd.type_none() # DC for size usually means not this specific tuple type
|
|
||||||
)
|
|
||||||
|
|
||||||
# Wrap with primary tuple type check
|
|
||||||
raw_final_tdd =
|
|
||||||
Tdd.make_node_raw(
|
|
||||||
variable_prefix_module.@v_is_tuple,
|
|
||||||
size_check_node, # If is_tuple, proceed to size check
|
|
||||||
Tdd.type_none(), # If not a tuple, then false
|
|
||||||
Tdd.type_none() # DC for is_tuple usually means not this specific type
|
|
||||||
)
|
|
||||||
|
|
||||||
# Simplify the constructed TDD
|
|
||||||
Tdd.simplify_with_constraints(raw_final_tdd, %{})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
IO.puts("\n--- Specific Tuple Subtyping Test ---")
|
|
||||||
|
|
||||||
# Type for {1, :foo}
|
|
||||||
el1_type1 = Tdd.type_int_eq(1)
|
|
||||||
el2_type1 = Tdd.type_atom_literal(:foo)
|
|
||||||
tdd_tuple_1_foo = TupleTestHelpers.create_specific_tuple_type_h([el1_type1, el2_type1])
|
|
||||||
|
|
||||||
# Type for {int_gt_0, :foo | :bar}
|
|
||||||
el1_type2 = Tdd.type_int_gt(0)
|
|
||||||
el2_type2_foo = Tdd.type_atom_literal(:foo)
|
|
||||||
el2_type2_bar = Tdd.type_atom_literal(:bar)
|
|
||||||
el2_type2 = Tdd.sum(el2_type2_foo, el2_type2_bar)
|
|
||||||
tdd_tuple_int_gt0_foo_or_bar = TupleTestHelpers.create_specific_tuple_type_h([el1_type2, el2_type2])
|
|
||||||
|
|
||||||
# IO.puts("TDD for {1, :foo}:")
|
|
||||||
# Tdd.print_tdd(tdd_tuple_1_foo)
|
|
||||||
# IO.puts("TDD for {int_gt_0, :foo | :bar}:")
|
|
||||||
# Tdd.print_tdd(tdd_tuple_int_gt0_foo_or_bar)
|
|
||||||
|
|
||||||
test.(
|
|
||||||
"{1, :foo} <: {int_gt_0, :foo | :bar}",
|
|
||||||
true,
|
|
||||||
Tdd.is_subtype(tdd_tuple_1_foo, tdd_tuple_int_gt0_foo_or_bar)
|
|
||||||
)
|
|
||||||
|
|
||||||
IO.inspect(Process.get(:test_failures, []), label: "Current test failures after tuple test")
|
|
||||||
>>>>>>> REPLACE
|
|
||||||
```
|
|
||||||
|
|
||||||
> Tokens: 23k sent, 1.4k received. Cost: $0.04 message, $0.04 session.
|
|
||||||
> Applied edit to test.exs
|
|
||||||
> Processing your request...
|
|
||||||
|
|
||||||
Okay, I understand. The issue is that Elixir guards have restrictions on what functions can be called within them. Calls to `Tdd.type_any()` and `Tdd.type_none()` are considered "remote" calls in this context, even if they return simple values.
|
|
||||||
|
|
||||||
To fix this, I will replace the calls to `Tdd.type_any()` and `Tdd.type_none()` in the guard clauses with their literal return values.
|
|
||||||
- `Tdd.type_any()` returns `@true_node_id` which is `1`.
|
|
||||||
- `Tdd.type_none()` returns `@false_node_id` which is `0`.
|
|
||||||
|
|
||||||
I will make these changes and remove the "AI!" comment.
|
|
||||||
|
|
||||||
Here is the *SEARCH/REPLACE block*:
|
|
||||||
|
|
||||||
```elixir
|
|
||||||
test.exs
|
|
||||||
<<<<<<< SEARCH
|
|
||||||
defmodule TupleTestHelpers do
|
|
||||||
def build_tuple_element_tdd_h(_element_index, element_type_id, success_path_id, _variable_prefix_module)
|
|
||||||
# AI! You cannot use remote functions inside function guards
|
|
||||||
when element_type_id == Tdd.type_any() do
|
|
||||||
# If element type is 'any', this part of the check passes, go to success_path_id
|
|
||||||
success_path_id
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_tuple_element_tdd_h(_element_index, element_type_id, _success_path_id, _variable_prefix_module)
|
|
||||||
when element_type_id == Tdd.type_none() do
|
|
||||||
# If element type is 'none', this path fails
|
|
||||||
Tdd.type_none()
|
|
||||||
end
|
|
||||||
=======
|
|
||||||
defmodule TupleTestHelpers do
|
|
||||||
def build_tuple_element_tdd_h(_element_index, element_type_id, success_path_id, _variable_prefix_module)
|
|
||||||
when element_type_id == 1 do # Was Tdd.type_any()
|
|
||||||
# If element type is 'any', this part of the check passes, go to success_path_id
|
|
||||||
success_path_id
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_tuple_element_tdd_h(_element_index, element_type_id, _success_path_id, _variable_prefix_module)
|
|
||||||
when element_type_id == 0 do # Was Tdd.type_none()
|
|
||||||
# If element type is 'none', this path fails
|
|
||||||
Tdd.type_none()
|
|
||||||
end
|
|
||||||
>>>>>>> REPLACE
|
|
||||||
```
|
|
||||||
|
|
||||||
> Tokens: 25k sent, 457 received. Cost: $0.04 message, $0.08 session.
|
|
||||||
> Applied edit to test.exs
|
|
||||||
|
|||||||
@ -4182,6 +4182,3 @@
|
|||||||
|
|
||||||
# 2025-06-15 11:56:09.668461
|
# 2025-06-15 11:56:09.668461
|
||||||
+/context
|
+/context
|
||||||
|
|
||||||
# 2025-06-16 11:51:48.065221
|
|
||||||
+n
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user