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

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions