fix consistency checker
This commit is contained in:
parent
36f63ed355
commit
5736c30fa2
65
new.exs
65
new.exs
@ -716,7 +716,7 @@ defmodule Tdd.Consistency.Engine do
|
||||
end
|
||||
end
|
||||
|
||||
defp reduce_implication(_implication, _all, error, _), do: error
|
||||
defp reduce_implication(_implication, _all_assumptions, error_acc), do: error_acc
|
||||
|
||||
# --- Step 2: Flat Consistency Checks ---
|
||||
|
||||
@ -766,48 +766,51 @@ defmodule Tdd.Consistency.Engine do
|
||||
if is_empty and (has_head_prop or has_tail_prop), do: :error, else: :ok
|
||||
end
|
||||
|
||||
defp check_integer_consistency(assumptions) do
|
||||
# Reduce all integer-related assumptions to a single valid range [min, max].
|
||||
# If the range becomes invalid (min > max), it's a contradiction.
|
||||
defp check_integer_consistency(assumptions) do
|
||||
initial_range = {:neg_inf, :pos_inf}
|
||||
|
||||
result =
|
||||
Enum.reduce_while(assumptions, initial_range, fn assumption, {min, max} ->
|
||||
case assumption do
|
||||
# x < N => max becomes min(max, N-1)
|
||||
{{2, :alt, n, _}, true} -> narrow_range(min, :erlang.min(max, n - 1))
|
||||
# not (x < N) <=> x >= N => min becomes max(min, N)
|
||||
{{2, :alt, n, _}, false} -> narrow_range(:erlang.max(min, n), max)
|
||||
# x == N => min becomes max(min, N), max becomes min(max, N)
|
||||
{{2, :beq, n, _}, true} -> narrow_range(:erlang.max(min, n), :erlang.min(max, n))
|
||||
# x != N : this is only a contradiction if the range is exactly {N, N}
|
||||
{{2, :alt, n, _}, true} -> narrow_range(min, safe_min(max, n - 1))
|
||||
{{2, :alt, n, _}, false} -> narrow_range(safe_max(min, n), max)
|
||||
{{2, :beq, n, _}, true} -> narrow_range(safe_max(min, n), safe_min(max, n))
|
||||
{{2, :beq, n, _}, false} when min == n and max == n -> {:halt, :invalid}
|
||||
# x > N => min becomes max(min, N+1)
|
||||
{{2, :cgt, n, _}, true} -> narrow_range(:erlang.max(min, n + 1), max)
|
||||
# not (x > N) <=> x <= N => max becomes min(max, N)
|
||||
{{2, :cgt, n, _}, false} -> narrow_range(min, :erlang.min(max, n))
|
||||
# Not an integer assumption, continue.
|
||||
{{2, :cgt, n, _}, true} -> narrow_range(safe_max(min, n + 1), max)
|
||||
{{2, :cgt, n, _}, false} -> narrow_range(min, safe_min(max, n))
|
||||
_ -> {:cont, {min, max}}
|
||||
end
|
||||
end)
|
||||
|
||||
case result,
|
||||
do:
|
||||
(
|
||||
:invalid -> :error
|
||||
_ -> :ok
|
||||
)
|
||||
case result, do: (:invalid -> :error; _ -> :ok)
|
||||
end
|
||||
|
||||
# Helper to check if a new range is valid and continue/halt the reduction.
|
||||
# **IMPROVED**: A clearer implementation for checking range validity.
|
||||
defp narrow_range(min, max) do
|
||||
cond do
|
||||
min == :neg_inf or max == :pos_inf -> {:cont, {min, max}}
|
||||
min > max -> {:halt, :invalid}
|
||||
true -> {:cont, {min, max}}
|
||||
end
|
||||
is_invalid =
|
||||
case {min, max} do
|
||||
{:neg_inf, _} -> false
|
||||
{_, :pos_inf} -> false
|
||||
{m, n} when is_integer(m) and is_integer(n) -> m > n
|
||||
_ -> false # Should not happen with safe helpers
|
||||
end
|
||||
|
||||
if is_invalid, do: {:halt, :invalid}, else: {:cont, {min, max}}
|
||||
end
|
||||
|
||||
# **NEW**: Safe comparison helpers that understand :neg_inf and :pos_inf
|
||||
defp safe_max(:neg_inf, x), do: x
|
||||
defp safe_max(x, :neg_inf), do: x
|
||||
defp safe_max(:pos_inf, _), do: :pos_inf
|
||||
defp safe_max(_, :pos_inf), do: :pos_inf
|
||||
defp safe_max(a, b), do: :erlang.max(a, b)
|
||||
|
||||
defp safe_min(:pos_inf, x), do: x
|
||||
defp safe_min(x, :pos_inf), do: x
|
||||
defp safe_min(:neg_inf, _), do: :neg_inf
|
||||
defp safe_min(_, :neg_inf), do: :neg_inf
|
||||
defp safe_min(a, b), do: :erlang.min(a, b)
|
||||
|
||||
# --- Step 3: Recursive Consistency (Disabled but preserved) ---
|
||||
defp check_recursive_consistency(assumptions, full_context) do
|
||||
# 1. Gather all ambient constraints from the parent context.
|
||||
@ -1791,9 +1794,9 @@ defmodule ConsistencyEngineTests do
|
||||
test("A single valid assumption is consistent", :consistent, %{Variable.v_is_atom() => true})
|
||||
|
||||
test(
|
||||
"An explicit contradiction is caught",
|
||||
"An implied contradiction is caught by expander",
|
||||
:contradiction,
|
||||
%{Variable.v_is_atom() => true, Variable.v_is_atom() => false}
|
||||
%{Variable.v_atom_eq(:foo) => true, Variable.v_is_atom() => false}
|
||||
)
|
||||
|
||||
test(
|
||||
@ -2368,5 +2371,5 @@ TddStoreTests.run()
|
||||
TddVariableTests.run()
|
||||
# TddAlgoTests.run()
|
||||
ConsistencyEngineTests.run()
|
||||
# TypeReconstructorTests.run()
|
||||
TypeReconstructorTests.run()
|
||||
# CompilerAlgoTests.run()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user