Skip to content

Support ForwardDiff duals over BareInterval - #778

Open
timholy wants to merge 3 commits into
JuliaIntervals:masterfrom
timholy:teh/fd-bare
Open

timholy wants to merge 3 commits into
JuliaIntervals:masterfrom
timholy:teh/fd-bare

Conversation

@timholy

@timholy timholy commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

This has two commits; the second depends on the first, but arguably they should be merged without squashing. I can also split into two separate (sequential) PRs if you prefer.

The main goal here is to support differentiation and arithmetic for bare intervals in nested duals. At present I think this is the last performance work I need to make it possible to adopt IA.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results (Julia v1)

Time benchmarks
master f64c50b... master / f64c50b...
BigFloat MPFI/basics/* 26.3 ± 3.6 μs 26.6 ± 3.6 μs 0.991 ± 0.19
BigFloat MPFI/basics/+ 13.4 ± 3.4 μs 13.9 ± 3.5 μs 0.965 ± 0.34
BigFloat MPFI/basics/- 19.2 ± 3.7 μs 19.1 ± 3.5 μs 1.01 ± 0.27
BigFloat MPFI/basics// 25.7 ± 7.2 μs 26.2 ± 6.8 μs 0.98 ± 0.38
BigFloat MPFI/basics/abs 11.3 ± 3.4 μs 11 ± 3.4 μs 1.03 ± 0.45
BigFloat MPFI/basics/acos 0.698 ± 0.0091 ms 0.681 ± 0.0089 ms 1.02 ± 0.019
BigFloat MPFI/basics/asin 0.679 ± 0.011 ms 0.666 ± 0.011 ms 1.02 ± 0.024
BigFloat MPFI/basics/atan 2.11 ± 0.0073 ms 2.1 ± 0.008 ms 1 ± 0.0051
BigFloat MPFI/basics/cos 0.359 ± 0.01 ms 0.36 ± 0.01 ms 0.999 ± 0.039
BigFloat MPFI/basics/cosh 0.431 ± 0.012 ms 0.432 ± 0.012 ms 1 ± 0.04
BigFloat MPFI/basics/exp 0.502 ± 0.01 ms 0.501 ± 0.0098 ms 1 ± 0.028
BigFloat MPFI/basics/inv 19.4 ± 3.6 μs 19.5 ± 3.6 μs 0.993 ± 0.26
BigFloat MPFI/basics/log 0.469 ± 0.011 ms 0.465 ± 0.01 ms 1.01 ± 0.032
BigFloat MPFI/basics/sin 0.468 ± 0.011 ms 0.466 ± 0.011 ms 1 ± 0.034
BigFloat MPFI/basics/sinh 0.572 ± 0.01 ms 0.573 ± 0.0099 ms 0.997 ± 0.025
BigFloat MPFI/basics/sqrt 22.8 ± 3.5 μs 21.9 ± 3.7 μs 1.04 ± 0.24
BigFloat MPFI/basics/tan 0.386 ± 0.01 ms 0.385 ± 0.01 ms 1 ± 0.037
BigFloat MPFI/basics/tanh 0.586 ± 0.01 ms 0.589 ± 0.01 ms 0.996 ± 0.024
BigFloat bareinterval/basics/* 0.04 ± 0.0025 ms 0.0405 ± 0.0025 ms 0.988 ± 0.087
BigFloat bareinterval/basics/+ 22.9 ± 3.3 μs 23.1 ± 3.4 μs 0.992 ± 0.2
BigFloat bareinterval/basics/- 23.3 ± 3.3 μs 24.4 ± 3.5 μs 0.956 ± 0.19
BigFloat bareinterval/basics// 20 ± 5 μs 20.8 ± 5 μs 0.962 ± 0.33
BigFloat bareinterval/basics/abs 15 ± 3.2 μs 15.3 ± 3.3 μs 0.98 ± 0.3
BigFloat bareinterval/basics/acos 0.714 ± 0.014 ms 0.715 ± 0.013 ms 0.999 ± 0.027
BigFloat bareinterval/basics/asin 0.726 ± 0.014 ms 0.708 ± 0.013 ms 1.03 ± 0.027
BigFloat bareinterval/basics/atan 2.12 ± 0.0082 ms 2.1 ± 0.0074 ms 1.01 ± 0.0052
BigFloat bareinterval/basics/cos 0.415 ± 0.084 ms 0.416 ± 0.086 ms 0.998 ± 0.29
BigFloat bareinterval/basics/cosh 0.479 ± 0.012 ms 0.478 ± 0.011 ms 1 ± 0.034
BigFloat bareinterval/basics/exp 0.512 ± 0.011 ms 0.512 ± 0.011 ms 1 ± 0.029
BigFloat bareinterval/basics/inv 26.2 ± 3.2 μs 27 ± 3.4 μs 0.97 ± 0.17
BigFloat bareinterval/basics/log 0.502 ± 0.011 ms 0.5 ± 0.011 ms 1 ± 0.032
BigFloat bareinterval/basics/sin 0.553 ± 0.083 ms 0.554 ± 0.082 ms 0.999 ± 0.21
BigFloat bareinterval/basics/sinh 0.582 ± 0.011 ms 0.582 ± 0.011 ms 0.999 ± 0.026
BigFloat bareinterval/basics/sqrt 31.2 ± 2.4 μs 0.0317 ± 0.0027 ms 0.987 ± 0.12
BigFloat bareinterval/basics/tan 0.322 ± 0.056 ms 0.325 ± 0.056 ms 0.991 ± 0.24
BigFloat bareinterval/basics/tanh 0.596 ± 0.01 ms 0.596 ± 0.011 ms 1 ± 0.025
BigFloat interval/basics/* 0.043 ± 0.012 ms 0.0445 ± 0.012 ms 0.965 ± 0.36
BigFloat interval/basics/+ 17.9 ± 0.69 μs 19.3 ± 0.53 μs 0.929 ± 0.044
BigFloat interval/basics/- 18.5 ± 0.35 μs 18.1 ± 0.27 μs 1.02 ± 0.025
BigFloat interval/basics// 20.9 ± 0.25 μs 22 ± 0.21 μs 0.951 ± 0.015
BigFloat interval/basics/abs 14.7 ± 8.1 μs 15 ± 7.8 μs 0.979 ± 0.74
BigFloat interval/basics/acos 0.707 ± 0.038 ms 0.708 ± 0.034 ms 0.999 ± 0.072
BigFloat interval/basics/asin 0.695 ± 0.0099 ms 0.69 ± 0.011 ms 1.01 ± 0.021
BigFloat interval/basics/atan 2.12 ± 0.0089 ms 2.11 ± 0.0055 ms 1.01 ± 0.005
BigFloat interval/basics/cos 0.335 ± 0.013 ms 0.336 ± 0.013 ms 0.996 ± 0.054
BigFloat interval/basics/cosh 0.468 ± 0.011 ms 0.47 ± 0.011 ms 0.997 ± 0.034
BigFloat interval/basics/exp 0.522 ± 0.0093 ms 0.521 ± 0.0095 ms 1 ± 0.026
BigFloat interval/basics/inv 22.2 ± 0.27 μs 23.3 ± 0.25 μs 0.954 ± 0.016
BigFloat interval/basics/log 0.502 ± 0.013 ms 0.499 ± 0.013 ms 1.01 ± 0.036
BigFloat interval/basics/sin 0.483 ± 0.013 ms 0.484 ± 0.013 ms 0.997 ± 0.039
BigFloat interval/basics/sinh 0.59 ± 0.01 ms 0.591 ± 0.01 ms 0.998 ± 0.024
BigFloat interval/basics/sqrt 0.0392 ± 0.0012 ms 0.0392 ± 0.0011 ms 1 ± 0.04
BigFloat interval/basics/tan 0.281 ± 0.012 ms 0.281 ± 0.012 ms 1 ± 0.061
BigFloat interval/basics/tanh 0.605 ± 0.0097 ms 0.605 ± 0.0095 ms 1 ± 0.023
bareinterval/basics/* 1.82 ± 0.049 μs 1.82 ± 0.05 μs 1 ± 0.038
bareinterval/basics/+ 0.491 ± 0.01 μs 0.481 ± 0.01 μs 1.02 ± 0.03
bareinterval/basics/- 0.501 ± 0.01 μs 0.501 ± 0.01 μs 1 ± 0.028
bareinterval/basics// 1.17 ± 0.04 μs 1.17 ± 0.031 μs 1 ± 0.043
bareinterval/basics/abs 0.16 ± 0.011 μs 0.16 ± 0.011 μs 1 ± 0.097
bareinterval/basics/acos 2.69 ± 0.011 μs 2.71 ± 0.01 μs 0.989 ± 0.0054
bareinterval/basics/asin 2.98 ± 0.03 μs 2.99 ± 0.031 μs 0.997 ± 0.014
bareinterval/basics/atan 13 ± 0.25 μs 13.2 ± 0.16 μs 0.981 ± 0.022
bareinterval/basics/cos 0.0684 ± 0.021 ms 0.0682 ± 0.02 ms 1 ± 0.42
bareinterval/basics/cosh 7.17 ± 0.031 μs 7.16 ± 0.031 μs 1 ± 0.0061
bareinterval/basics/exp 4.28 ± 0.05 μs 4.27 ± 0.05 μs 1 ± 0.017
bareinterval/basics/inv 0.902 ± 0.021 μs 0.902 ± 0.04 μs 1 ± 0.05
bareinterval/basics/log 6.4 ± 0.031 μs 6.28 ± 0.04 μs 1.02 ± 0.0082
bareinterval/basics/sin 0.0671 ± 0.02 ms 0.0669 ± 0.02 ms 1 ± 0.42
bareinterval/basics/sinh 10.1 ± 0.06 μs 10.1 ± 0.061 μs 0.999 ± 0.0085
bareinterval/basics/sqrt 1.1 ± 0.02 μs 1.09 ± 0.02 μs 1.01 ± 0.026
bareinterval/basics/tan 0.0383 ± 0.0024 ms 0.0386 ± 0.0025 ms 0.991 ± 0.091
bareinterval/basics/tanh 0.306 ± 0.0096 ms 0.306 ± 0.0096 ms 0.998 ± 0.044
interval/basics/* 2.77 ± 0.06 μs 2.98 ± 0.071 μs 0.929 ± 0.03
interval/basics/+ 1.34 ± 0.031 μs 1.53 ± 0.049 μs 0.875 ± 0.035
interval/basics/- 1.36 ± 0.031 μs 1.56 ± 0.04 μs 0.871 ± 0.03
interval/basics// 1.83 ± 0.2 μs 2.04 ± 0.25 μs 0.898 ± 0.15
interval/basics/abs 0.351 ± 0.05 μs 0.351 ± 0.07 μs 1 ± 0.25
interval/basics/acos 3.28 ± 0.06 μs 3.28 ± 0.05 μs 1 ± 0.024
interval/basics/asin 3.56 ± 0.041 μs 3.56 ± 0.049 μs 1 ± 0.018
interval/basics/atan 13.3 ± 0.21 μs 13.2 ± 0.22 μs 1 ± 0.023
interval/basics/cos 0.0519 ± 0.018 ms 0.0524 ± 0.019 ms 0.991 ± 0.5
interval/basics/cosh 8.91 ± 0.08 μs 8.92 ± 0.071 μs 0.999 ± 0.012
interval/basics/exp 4.77 ± 0.06 μs 4.79 ± 0.051 μs 0.996 ± 0.016
interval/basics/inv 1.35 ± 0.029 μs 1.39 ± 0.039 μs 0.971 ± 0.034
interval/basics/log 2.52 ± 0.051 μs 2.5 ± 0.06 μs 1 ± 0.032
interval/basics/sin 0.0672 ± 0.0033 ms 0.0675 ± 0.0034 ms 0.996 ± 0.07
interval/basics/sinh 10.5 ± 0.071 μs 10.5 ± 0.081 μs 0.996 ± 0.01
interval/basics/sqrt 1.53 ± 0.05 μs 1.55 ± 0.05 μs 0.988 ± 0.045
interval/basics/tan 0.0387 ± 0.0019 ms 0.0388 ± 0.002 ms 0.998 ± 0.069
interval/basics/tanh 0.306 ± 0.012 ms 0.307 ± 0.013 ms 0.998 ± 0.059
time_to_load 0.107 ± 0.00074 s 0.108 ± 0.0023 s 0.994 ± 0.022
Memory benchmarks
master f64c50b... master / f64c50b...
BigFloat MPFI/basics/* 0.424 k allocs: 21.3 kB 0.424 k allocs: 21.3 kB 1
BigFloat MPFI/basics/+ 0.302 k allocs: 16.5 kB 0.302 k allocs: 16.5 kB 1
BigFloat MPFI/basics/- 0.402 k allocs: 20.4 kB 0.402 k allocs: 20.4 kB 1
BigFloat MPFI/basics// 0.345 k allocs: 18.2 kB 0.345 k allocs: 18.2 kB 1
BigFloat MPFI/basics/abs 0.324 k allocs: 17.4 kB 0.324 k allocs: 17.4 kB 1
BigFloat MPFI/basics/acos 1.24 k allocs: 0.0445 MB 1.24 k allocs: 0.0445 MB 1
BigFloat MPFI/basics/asin 1.08 k allocs: 0.0417 MB 1.08 k allocs: 0.0417 MB 1
BigFloat MPFI/basics/atan 2.14 k allocs: 0.0543 MB 2.14 k allocs: 0.0543 MB 1
BigFloat MPFI/basics/cos 2.9 k allocs: 0.0975 MB 2.9 k allocs: 0.0975 MB 1
BigFloat MPFI/basics/cosh 0.781 k allocs: 0.0322 MB 0.781 k allocs: 0.0322 MB 1
BigFloat MPFI/basics/exp 0.902 k allocs: 0.036 MB 0.902 k allocs: 0.036 MB 1
BigFloat MPFI/basics/inv 0.351 k allocs: 18.4 kB 0.351 k allocs: 18.4 kB 1
BigFloat MPFI/basics/log 0.407 k allocs: 20.6 kB 0.407 k allocs: 20.6 kB 1
BigFloat MPFI/basics/sin 3.18 k allocs: 0.106 MB 3.18 k allocs: 0.106 MB 1
BigFloat MPFI/basics/sinh 0.915 k allocs: 0.0369 MB 0.915 k allocs: 0.0369 MB 1
BigFloat MPFI/basics/sqrt 0.302 k allocs: 16.5 kB 0.302 k allocs: 16.5 kB 1
BigFloat MPFI/basics/tan 2.8 k allocs: 0.098 MB 2.8 k allocs: 0.098 MB 1
BigFloat MPFI/basics/tanh 0.908 k allocs: 0.0362 MB 0.908 k allocs: 0.0362 MB 1
BigFloat bareinterval/basics/* 0.262 k allocs: 26 kB 0.262 k allocs: 26 kB 1
BigFloat bareinterval/basics/+ 0.202 k allocs: 20.4 kB 0.202 k allocs: 20.4 kB 1
BigFloat bareinterval/basics/- 0.202 k allocs: 20.4 kB 0.202 k allocs: 20.4 kB 1
BigFloat bareinterval/basics// 0.1 k allocs: 10.8 kB 0.1 k allocs: 10.8 kB 1
BigFloat bareinterval/basics/abs 0.199 k allocs: 20.1 kB 0.199 k allocs: 20.1 kB 1
BigFloat bareinterval/basics/acos 1.27 k allocs: 0.0692 MB 1.27 k allocs: 0.0692 MB 1
BigFloat bareinterval/basics/asin 1.17 k allocs: 0.0659 MB 1.17 k allocs: 0.0659 MB 1
BigFloat bareinterval/basics/atan 2.04 k allocs: 0.058 MB 2.04 k allocs: 0.058 MB 1
BigFloat bareinterval/basics/cos 2.45 k allocs: 0.185 MB 2.45 k allocs: 0.185 MB 1
BigFloat bareinterval/basics/cosh 1.01 k allocs: 0.0671 MB 1.01 k allocs: 0.0671 MB 1
BigFloat bareinterval/basics/exp 0.802 k allocs: 0.0397 MB 0.802 k allocs: 0.0397 MB 1
BigFloat bareinterval/basics/inv 0.198 k allocs: 20 kB 0.198 k allocs: 20 kB 1
BigFloat bareinterval/basics/log 0.616 k allocs: 0.0522 MB 0.616 k allocs: 0.0522 MB 1
BigFloat bareinterval/basics/sin 2.9 k allocs: 0.197 MB 2.9 k allocs: 0.197 MB 1
BigFloat bareinterval/basics/sinh 0.815 k allocs: 0.0407 MB 0.815 k allocs: 0.0407 MB 1
BigFloat bareinterval/basics/sqrt 0.26 k allocs: 25.8 kB 0.26 k allocs: 25.8 kB 1
BigFloat bareinterval/basics/tan 1.67 k allocs: 0.124 MB 1.67 k allocs: 0.124 MB 1
BigFloat bareinterval/basics/tanh 0.808 k allocs: 0.0399 MB 0.808 k allocs: 0.0399 MB 1
BigFloat interval/basics/* 0.263 k allocs: 26.8 kB 0.263 k allocs: 26.8 kB 1
BigFloat interval/basics/+ 0.203 k allocs: 21.2 kB 0.203 k allocs: 21.2 kB 1
BigFloat interval/basics/- 0.203 k allocs: 21.2 kB 0.203 k allocs: 21.2 kB 1
BigFloat interval/basics// 0.101 k allocs: 11.6 kB 0.101 k allocs: 11.6 kB 1
BigFloat interval/basics/abs 0.2 k allocs: 20.9 kB 0.2 k allocs: 20.9 kB 1
BigFloat interval/basics/acos 1.71 k allocs: 0.11 MB 1.71 k allocs: 0.11 MB 0.998
BigFloat interval/basics/asin 1.47 k allocs: 0.0944 MB 1.47 k allocs: 0.0946 MB 0.998
BigFloat interval/basics/atan 2.04 k allocs: 0.0595 MB 2.04 k allocs: 0.0593 MB 1
BigFloat interval/basics/cos 2.45 k allocs: 0.186 MB 2.45 k allocs: 0.186 MB 1
BigFloat interval/basics/cosh 1.01 k allocs: 0.068 MB 1.01 k allocs: 0.068 MB 1
BigFloat interval/basics/exp 0.803 k allocs: 0.0407 MB 0.803 k allocs: 0.0407 MB 0.999
BigFloat interval/basics/inv 0.199 k allocs: 20.8 kB 0.199 k allocs: 20.8 kB 1
BigFloat interval/basics/log 0.917 k allocs: 0.0805 MB 0.917 k allocs: 0.0805 MB 1
BigFloat interval/basics/sin 2.9 k allocs: 0.198 MB 2.9 k allocs: 0.198 MB 1
BigFloat interval/basics/sinh 0.816 k allocs: 0.0416 MB 0.816 k allocs: 0.0416 MB 0.999
BigFloat interval/basics/sqrt 0.714 k allocs: 0.0675 MB 0.714 k allocs: 0.0675 MB 1
BigFloat interval/basics/tan 1.67 k allocs: 0.125 MB 1.67 k allocs: 0.125 MB 1
BigFloat interval/basics/tanh 0.809 k allocs: 0.0409 MB 0.809 k allocs: 0.0408 MB 1
bareinterval/basics/* 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/+ 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/- 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics// 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/abs 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/acos 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/asin 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/atan 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/cos 0.56 k allocs: 0.0423 MB 0.56 k allocs: 0.0423 MB 1
bareinterval/basics/cosh 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/exp 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/inv 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/log 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/sin 0.56 k allocs: 0.0423 MB 0.56 k allocs: 0.0423 MB 1
bareinterval/basics/sinh 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/sqrt 2 allocs: 1.62 kB 2 allocs: 1.62 kB 1
bareinterval/basics/tan 0.29 k allocs: 23.1 kB 0.29 k allocs: 23.1 kB 1
bareinterval/basics/tanh 1.03 k allocs: 0.0359 MB 1.03 k allocs: 0.0359 MB 1
interval/basics/* 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/+ 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/- 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics// 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/abs 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/acos 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/asin 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/atan 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/cos 0.561 k allocs: 0.0431 MB 0.561 k allocs: 0.0431 MB 1
interval/basics/cosh 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/exp 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/inv 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/log 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/sin 0.561 k allocs: 0.0431 MB 0.561 k allocs: 0.0431 MB 1
interval/basics/sinh 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/sqrt 3 allocs: 2.45 kB 3 allocs: 2.45 kB 1
interval/basics/tan 0.291 k allocs: 24 kB 0.291 k allocs: 24 kB 1
interval/basics/tanh 1.03 k allocs: 0.0367 MB 1.03 k allocs: 0.0367 MB 1
time_to_load 0.201 k allocs: 11.8 kB 0.201 k allocs: 11.8 kB 1

@OlivierHnt

Copy link
Copy Markdown
Member

Looks good to me. I wonder whether we just never got around implementing ForwardDiff for BareInterval, or if there was a deeper reason?
@Kolaru can you have a look?

@Kolaru Kolaru left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for the PR!

As I mention in comment, to me it looks like that this PR introduce a design that is not guaranteed. And (unfortunately T_T), I think we need to figure that out before we can move forward.

Comment thread ext/IntervalArithmeticForwardDiffExt.jl Outdated
Comment thread ext/IntervalArithmeticForwardDiffExt.jl Outdated
Comment thread ext/IntervalArithmeticForwardDiffExt.jl Outdated
Add integer and rational exponents, including literal integer powers.

Assisted-by: Claude Opus 5 <noreply@anthropic.com>
Add differentiation and arithmetic for bare intervals in nested duals.
Use thin-zero checks for interval partials in power rules and, when
supported by ForwardDiff, its zero-partial checks.

Treat real constants and derivative coefficients as exact. Callers who
need to track this assumption through `isguaranteed` should use decorated
intervals.

Assisted-by: Claude Fable 5 (claude-fable-5) <noreply@anthropic.com>
@timholy

timholy commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

I've rebased on current master and hopefully addressed @Kolaru's concerns.

This allows FD support without defining operations against inexact quantities

Assisted-by: Claude Fable 5.1 <noreply@anthropic.com>
@timholy

timholy commented Sep 19, 2026

Copy link
Copy Markdown
Contributor Author

If you do want to merge this as two commits, LMK and I can squash everything after the first commit together, leaving the first distinct.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants