Ticket #8490 (closed defect: fixed)

Opened 3 years ago

Last modified 3 years ago

Bad behavior of is_square_free for Words

Reported by: vdelecroix Owned by: vdelecroix
Priority: major Milestone: sage-4.4.4
Component: combinatorics Keywords: word
Cc: sage-combinat Work issues:
Report Upstream: N/A Reviewers: Mike Hansen, Nathann Cohen
Authors: Vincent Delecroix, Sébastien Labbé Merged in: sage-4.4.4.alpha0
Dependencies: Stopgaps:

Description (last modified by vdelecroix) (diff)

The method is_square_free of sage.combinat.words.word.Word returns the wrong value in special cases (including squares !)

sage: Word("aa").is_square_free()  # the funniest
True
sage: Word("baa").is_square_free()
True
sage: Word("cbaa").is_square_free()
True
sage: Word("dcbaa").is_square_free()
True

Attachments

trac_8490-square_free-vd.2.patch Download (755 bytes) - added by vdelecroix 3 years ago.
another one-line correction that applies after #8429
trac_8490-square_free-vd.3.patch Download (755 bytes) - added by vdelecroix 3 years ago.
another one-line correction that applies after #8429
trac_8490-square_free-vd.patch Download (1.1 KB) - added by vdelecroix 3 years ago.
Apply only this
trac_8490_review-sl.patch Download (4.7 KB) - added by slabbe 3 years ago.
Applies over the precedent patch

Change History

comment:1 Changed 3 years ago by vdelecroix

  • Status changed from new to needs_review

comment:2 Changed 3 years ago by vdelecroix

  • Description modified (diff)

comment:3 Changed 3 years ago by mhansen

  • Status changed from needs_review to positive_review
  • Reviewers set to Mike Hansen
  • Authors changed from vdelecroix to Vincent Delecroix

Looks good to me.

comment:4 Changed 3 years ago by vdelecroix

  • Status changed from positive_review to needs_work

Oups, intersection with #8429 which refactors the code of sage.combinat.words.

I post soon a new patch that apply only after #8429 and I think it's better.

Changed 3 years ago by vdelecroix

another one-line correction that applies after #8429

Changed 3 years ago by vdelecroix

another one-line correction that applies after #8429

Changed 3 years ago by vdelecroix

Apply only this

comment:5 Changed 3 years ago by slabbe

The same bug was occuring with is_cube_free :

sage: Word('111').is_cube_free()
True
sage: Word('2111').is_cube_free()
True
sage: Word('32111').is_cube_free()
True

I just applied a patch which fixes this problem. I changed some doctests of both is_square_free and is_cube_free. I also removed a useless slice in the code of both functions and this gives good improvements in timings :

BEFORE:

sage: t = words.ThueMorseWord()
sage: %timeit t[:100].is_cube_free()
5 loops, best of 3: 3.13 s per loop

AFTER:

sage: t = words.ThueMorseWord()
sage: %timeit t[:100].is_cube_free()
5 loops, best of 3: 1.18 s per loop

Changed 3 years ago by slabbe

Applies over the precedent patch

comment:6 Changed 3 years ago by slabbe

  • Status changed from needs_work to needs_review
  • Authors changed from Vincent Delecroix to Vincent Delecroix, Sébastien Labbé

comment:7 follow-up: ↓ 9 Changed 3 years ago by ncohen

Hello !! This patch is finem except for a small unimportant thing which bothered me :

for end in xrange(start+3, L+1, 3): 

Why go up to L+1 when the last letter is L-1 ? The algorithm is still correct as

Word("abc")[:50000]

raises no exception, but as there is no reason to.... So I give a positive review to the patches above, and trac_8490_review-ncohen.patch is left to be reviewed by anyone other than me (quoting Minh) :-)

Thank you for this patch !!

Nathann

comment:8 follow-up: ↓ 10 Changed 3 years ago by ncohen

The patches are to be applied in this order :

  • trac_8490-square_free-vd.patch
  • trac_8490_review-sl.patch
  • trac_8490_review-ncohen.patch

Nathann

comment:9 in reply to: ↑ 7 Changed 3 years ago by slabbe

Replying to ncohen:

Hello !! This patch is finem except for a small unimportant thing which bothered me :

for end in xrange(start+3, L+1, 3): 

Why go up to L+1 when the last letter is L-1 ?

First, xrange returns a left-closed and right-open interval. Hence, one needs to write something like xrange(0,L+1) if one wants to go up to L :

sage: list(xrange(0,5))
[0, 1, 2, 3, 4]

Second, the variable end is not used to get a specific item in self but for slicing self. Hence, if one wants to consider all the slicing possibilities, the variable end must take the last possible value L:

sage: list(xrange(0,5)) [2:5]   #is good
[2, 3, 4]
sage: list(xrange(0,5)) [2:4]   #forgets the last letter
[2, 3]

Hence, your patch is strange in the sense that doctests should not pass!

The algorithm is still correct as

Word("abc")[:50000]

raises no exception, but as there is no reason to....

We made the choice of following the Python behavior for slices that goes too far:

sage: L = range(10)
sage: L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
sage: L[:100]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Sébastien

comment:10 in reply to: ↑ 8 Changed 3 years ago by slabbe

Replying to ncohen:

The patches are to be applied in this order :

  • trac_8490-square_free-vd.patch
  • trac_8490_review-sl.patch
  • trac_8490_review-ncohen.patch

Nathann

The patch trac_8490_review-ncohen.patch reintroduce the same bug as the current ticket is trying to solve. Hence, I think the patches are to be reviewed in this order again :

  • trac_8490-square_free-vd.patch
  • trac_8490_review-sl.patch

Sébastien

comment:11 Changed 3 years ago by ncohen

Perfectly right !! sorryyyyyyyyyyy !!! :-)

Nathann

comment:12 Changed 3 years ago by ncohen

  • Status changed from needs_review to positive_review

Well, then short of this, which was my mistake, I noticed nothing wrong with these two patches ! :-)

Nathann

comment:13 Changed 3 years ago by mhansen

  • Status changed from positive_review to closed
  • Reviewers changed from Mike Hansen to Mike Hansen, Nathann Cohen
  • Resolution set to fixed
  • Merged in set to sage-4.4.4.alpha0
Note: See TracTickets for help on using tickets.