Skip to content

Add delete to Data.List.Base? #988

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
mechvel opened this issue Nov 30, 2019 · 12 comments
Open

Add delete to Data.List.Base? #988

mechvel opened this issue Nov 30, 2019 · 12 comments
Labels

Comments

@mechvel
Copy link
Contributor

mechvel commented Nov 30, 2019

Consider

delete : (p? : Decidable P) → List A → List A
                                             -- delete the first x such that P x

What standard library has for this?

@gallais
Copy link
Member

gallais commented Nov 30, 2019

I don't think so. You could use Any's _─_
together with Any's any.

@mechvel
Copy link
Contributor Author

mechvel commented Dec 1, 2019

Any._-_ is good.
But the above delete is not given Any P xs, so that delete p? xs sometimes returns xs.
May be delete is worth adding, I do not know.

@MatthewDaggitt
Copy link
Contributor

@mechvel as always feel free to open a PR.

@jamesmckinna
Copy link
Contributor

Cf. #989
All.decide was added in #1595 so you could in v2.1 define

module _ (P? : Decidable P) where

  private
    helper :  xs  All (∁ P) xs ⊎ Any P xs
    helper = All.decide (Sum.swap ∘ (Dec.toSum ∘ P?))

  delete : List _  List _
  delete xs with helper xs
  ... | inj₁ _ = xs
  ... | inj₂ p = xs Any.─ p

But it's not clear (to me, at least) which, if any, of helper or delete belongs in the library, by contrast with All.decide?
Suggest closing this issue?

@mechvel
Copy link
Contributor Author

mechvel commented Jul 2, 2024

Personally I do not know. Currently I use my home-made functions

delP :  {xs : List A} → Any P xs → List A
delP {_ ∷ xs} (here _)        =  xs
delP {x ∷ xs} (there anyP-xs) =  x ∷ (delP anyP-xs)

delBy : (P? : Decidable P) → List A → List A
                                -- Delete the first x in xs such that P x, or return  xs  if there is not such x.
delBy _  []        =  []
delBy P? (x ∷ xs)  with P? x
... | yes _ =  xs
... | no _  =  x ∷ (delBy P? xs)

If the standard library announces an adequate replacement for them, then I would use the standard functions.
I also have several proofs for these functions:

delBy-preserves∈ :  (P? : Decidable P) → ∀ {x xs} → ¬ P x → x ∈ xs → x ∈ (delBy P? xs)

delBy-preserves-All :  (P? : Decidable P) → ∀ {β} (Q : Pred A β) {xs : List A} → All Q xs →
                                       All Q (delBy P? xs)
  
length-delBy-for-any :  (P? : Decidable P) → ∀ {xs} → Any P xs → length (delBy P? xs) ≡ pred (length xs)

and some others.

@jamesmckinna
Copy link
Contributor

... Currently I use my home-made functions

delP :  {xs : List A} → Any P xs → List A
delP {_ ∷ xs} (here _)        =  xs
delP {x ∷ xs} (there anyP-xs) =  x ∷ (delP anyP-xs)

You should find (and be able to prove ;-)) that this is extensionally equivalent to Any._─_ as previously suggested, so it's not obvious to me that you gain anything from this (slightly more direct) definition, which is the fusion of the two functions removeAt and index defining the library version...

@mechvel
Copy link
Contributor Author

mechvel commented Jul 2, 2024

You should find (and be able to prove ;-)) that this is extensionally equivalent to Any. as previously suggested,
so it's not obvious to me that you gain anything from this slightly more direct) definition, which is the fusion of the two
functions removeAt and index defining the library version...

First, this delP was used under lib-2.0, and I have now an impression that Any._─_ will appear after lib-2.1-rc1.
Second, it is sometimes difficult to understand standard functions, it takes effort. So, my application contains several
functions that can be replaced with standard ones.

functions removeAt and index defining the library version...

Is this index that returns a number in Fin ? Indexing members of a list with numbers?
Generally I have an impression that indexing a list with numbers needs to be avoided.
At least my large application avoids it, avoids index , avoids Fin , and feels all right.
Also suppose that I apply the fusion of the two functions removeAt and index to replace my delP.
As to me, the thing will not look more clear than the home-made implementation for delBy, delP.
I doubt.

@mechvel
Copy link
Contributor Author

mechvel commented Jul 2, 2024

Sorry, index can mean in stdlib something different from a number.
It may be a proof (i : x ∈ xs) for membership to a list.

@MatthewDaggitt
Copy link
Contributor

I would be happy to have delBy added to Data.List.Base under the name deleteFirst.

As @jamesmckinna says, delP already exists.

@jamesmckinna I'm not so keen on your version of delete as it appears to traverse the list twice?

@MatthewDaggitt MatthewDaggitt changed the title List.delete ? Add delete to Data.List.Base? Jul 4, 2024
@mechvel
Copy link
Contributor Author

mechvel commented Jul 4, 2024

Let the team decide.
Anyway, double reversing (if any) will be bad here. Because deleteFirst will be run by interpreter or in executable,
and it is easy to avoid double reversing.

@jamesmckinna
Copy link
Contributor

jamesmckinna commented Jul 4, 2024

Agree with @MatthewDaggitt that

deleteFirst : (P? : Decidable P)  List A  List A
                                -- Delete the first x in xs such that P x, or return  xs  if there is not such x.
deleteFirst _  []        =  []
deleteFirst P? (x ∷ xs)  with does (P? x)
... | true =  xs
... | false  =  x ∷ (deleteFirst P? xs)

@mechvel
Copy link
Contributor Author

mechvel commented Jul 4, 2024

Following jamesmckinna, I consider replacing my delP with Data.List.Relation.Unary.Any ._─_ :

_─_ : {P : Pred A p} → ∀ xs → Any P xs → List A
xs ─ x∈xs = removeAt xs (index x∈xs)

But I see now that index indeed finds a Number index in (Fin ...) .
So, _─_ first finds the number index for x , and then applies removeAt xs (index x∈xs) .
Do I understand correct that for xs = [0 .. n] = upTo n and n∈xs : n ∈ xs
the call xs ─ n∈xs takes 2*n steps to evaluate?
If so, then it is better to change the implementation of _─_ to the sample of

delP {_ ∷ xs} (here _)        =  xs
delP {x ∷ xs} (there anyP-xs) =  x ∷ (delP anyP-xs)

Because the latter takes n steps in the above example, and the function _─_ is not only for proofs, but also for interpreted evaluation and for running in executable.
?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants