Compare commits
8 Commits
de167ff5f3
...
5bf920da3a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bf920da3a | ||
|
|
72d851d71b | ||
|
|
fde8d2aedd | ||
|
|
dba5f720a6 | ||
|
|
1ede4de72c | ||
|
|
cc62c5ce8e | ||
|
|
0dc535d052 | ||
|
|
becef5db2f |
@ -57232,3 +57232,209 @@ 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,3 +4182,6 @@
|
|||||||
|
|
||||||
# 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