Skip to content

list_tl underapproximates on difference type #15490

Description

@lukaszsamson

Existing issue

  • I have searched existing issues and could not find a duplicate.

Elixir and Erlang/OTP versions

Erlang/OTP 28 [erts-16.4.0.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]

Interactive Elixir (1.21.0-dev)

Operating system

any

Current behavior

The following code proves the bug. Here t is a set of all non empty lists with atom elements where not all of them are :a. This includes lists like [:b], [:a, :b], [:b, :a], [:b, :b], [:b, :a, :a], [:b, :a, :b], ... etc.

t = opt_difference(non_empty_list(atom()), non_empty_list(atom([:a])))

a tail of that difference should be list(atom()) as it includes [], [:b], [:a], [:a, :a], [:a, :b], ...
of which non_empty_list(atom([:a])) is a subtype

subtype?(non_empty_list(atom([:a])), list(atom))
true

yet the returned type is too narrow

{:ok, tl} = list_tl(t)
subtype?(non_empty_list(atom([:a])), tl)
false

Likely reason:

|> Enum.reduce(initial, fn {_list, last, _negs}, acc -> opt_union(acc, last) end)

reuses the original BDD with the negations instead of rebuilding from positive DNF leaves

Expected behavior

subtype?(non_empty_list(atom([:a])), tl) should return true, list_tl should not narrow the type

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions