180 views
 owned this note
---- # Victor GSoC Journal ## Timeline - https://developers.google.com/open-source/gsoc/timeline May 8 - June 1 - Community bonding period June 2 - Coding officially begins July 14 - 18:00 UTC - Midterm evaluations begin **July 18 - 18:00 UTC - Midterm evaluation deadline** July 14 - August 25 - Work period August 25 - September 1 - 18:00 UTC - Final week and evaluation **September 1 - 8 - 18:00 UTC - Final evaluation** ## Blog posts 1. [Introducing my GSoC 2025 project](https://victorma.ca/posts/gsoc-1/) 1. [Coding begins](https://victorma.ca/posts/gsoc-2/) 1. [A strange bug](https://victorma.ca/posts/gsoc-3/) 1. [Bugs, bugs, and more bugs!](https://victorma.ca/posts/gsoc-4/) 1. [My first design doc](https://victorma.ca/posts/gsoc-5/) 1. [It's alive!](http://victorma.ca/posts/gsoc-6/) 1. [When is an optimization not optimal?](http://victorma.ca/posts/gsoc-7/) 1. [This is a test post](http://victorma.ca/posts/gsoc-8/) 1. [Google Summer of Code final report ](http://victorma.ca/posts/gsoc-9/) ## Current tasks 1. ~~Set up blog.~~ 1. ~~Write [blog post 1](https://victorma.ca/posts/gsoc-1/).~~ 1. ~~Create a list of other crossword editors to look into.~~ 1. ~~Look into other crossword editors to see what construction aids they have.~~ 1. ~~Send email to Crossfire creator.~~ 1. ~~Create feature ideas doc, mainly (but not entirely) based on prior art investigation.~~ 1. ~~Write [blog post 2](https://victorma.ca/posts/gsoc-2/).~~ 1. ~~Fix the [word suggestions bug](https://gitlab.gnome.org/jrb/crosswords/-/issues/269).~~ 1. ~~Write [blog post 3](https://victorma.ca/posts/gsoc-3/).~~ 1. ~~Fix [rebus intersection bug](https://gitlab.gnome.org/jrb/crosswords/-/issues/268).~~ 1. ~~Remove second word suggestions list.~~ 1. ~~Write [blog post 4](https://victorma.ca/posts/gsoc-4/).~~ 1. ~~Investigate monospace font.~~ 1. ~~Create fill lookahead notes doc.~~ 1. ~~Write [blog post 5](https://victorma.ca/posts/gsoc-5/).~~ 1. ~~Create design proposal for fill lookahead.~~ 1. ~~Write blog post 6.~~ 1. ~~Get screenshots for printing.~~ 1. ~~Set up wiki.~~ 1. ~~Do docs-related issues.~~ 1. ~~Write blog post 7.~~ 1. ~~Implement lookahead.~~ 1. ~~Get initial MR merged.~~ 2. ~~Do additional optimizations, tests, etc.~~ 1. ~~Do blog post 8.~~ 1. ~~Do blog post 9.~~ 1. ~~Finish the design doc.~~ ## Documents 1. [Prior art investigation](https://pad.gnome.org/s/aGYPwTen5) 1. [Feature ideas for GNOME Crosswords](https://pad.gnome.org/s/dxgb8XiY4) 1. [Fill look-ahead problem](https://pad.gnome.org/s/Tl93B05Yp) 1. [`word-list.c` intersection code notes](https://pad.gnome.org/s/R5IvXtNwS) 1. [Intersection fix problem](https://pad.gnome.org/s/ggjo6YWov) 1. [Rebus bug notes](https://pad.gnome.org/s/QZBPeNvMH) 1. [GUADEC presentation notes](https://pad.gnome.org/s/z0kHYSRx9) 1. [Word fill lookahead notes](https://pad.gnome.org/s/h5dBIlcr2) 1. [Font testing](https://pad.gnome.org/s/6mTne5Ehs) 1. [Lookahead design doc](https://pad.gnome.org/s/OAL239g-o) 1. [CSP resources](https://pad.gnome.org/s/I7xOv-9wN) 1. [Word suggestion + word solver](https://pad.gnome.org/s/tjTRe2d5H) ## Journal ### 2025/November/12 * Completed final edit. ### 2025/November/11 * Finished forward checking doc. * Added a comment about being unsure what the implementation section should contain, compared to the algorithm overview at the top of the doc. * Finished `word-suggestion.md`. * Removed most of the content there, since it's a duplicate of what's in the individual docs. * Added a algorithm comparison table. * Finished `clue-helpers.md`. * I've cleaned up `word-suggestion.md` and `grid-helpers.md` to not have so much miscellaneous ramblings about the word suggestion algorithms (like turning forward-checking into a grid level algorithm, or estimating performance). I think I was trying to do too much in those docs, and it's not really necessary. They are much more focused now. ### 2025/November/10 * Adding sections to forward checking doc. * I think caching is a good idea and the implementation should be simple. ### 2025/November/09 * Fixing up forward checking doc. ### 2025/November/08 * Finished AC-3 doc. ### 2025/November/07 * Finished blog post. * Finished final submission. ### 2025/November/06 * Added links to the final report. * Reworked existing sections about word suggestion algorithm. * Added consequences and fix sections. ### 2025/November/05 * Finished project summary and word suggestion algorithm explanations in final report. ### 2025/November/04 * Planning out final blog post. ### 2025/November/03 * Spruced up the wiki home page with category headings. * Created wiki pages for the [docs](https://gitlab.gnome.org/jrb/crosswords/-/wikis/docs-review) and [naming](https://gitlab.gnome.org/jrb/crosswords/-/wikis/naming-problems) suggestions I wrote in this journal a while ago. * Need to get the final submission done as soon as possible. Going to make my final blog post and use it as the final submission. * Going to do this blog post before continuing on the design docs. * Once it's done, I'll send it to Jonathan for a quick review, before submitting, like the GSoC admins suggest. (Though the blog post can always be updated later.) * Things to include in the blog post: * Short summary / description of the work I did. * Links to any notable MRs. * Links to any notable issues. * Links to all MRs and issues. * Links to all design docs. * Links to all the wiki pages. * Links to all blog posts. * Link to this journal. * Created [Editor roadmap thoughts doc](https://gitlab.gnome.org/jrb/crosswords/-/wikis/editor-roadmap). ### 2025/October/31 * Meeting with Jonathan. ### 2025/October/30 * **To clarify in our next meeting:** * What is the scope of `crossword-aids.md`? If we include unches, then it is not only word-suggestion-algorithm related aids. Is this too broad to be useful? * There is a [long list of features](https://gitlab.gnome.org/jrb/crosswords/-/wikis/ideas) that could be considered *crossword aids*. * If `crossword-aids.md` is meant to answer: "If we implement AC-3 then what do we get"---then it should only include the aids that require AC-3. And it should be merged *into* `word-suggestion.md`. * *Construction aids* instead of *crossword aids*? * Should `word-suggestions.md` exist? * AC-3 doc ends a bit abruptly and doesn't include a description of the implementation like the other algorithm docs do. But that is because the only crossword-specific part is the CSP modelling. Otherwise, it's just the standard AC-3 algorithm, and it doesn't make sense to add pseudocode for that. * More editing. * While working on the crossword aids document, I realize I never made a wiki page to store all the ideas I came up with. So I've created a new [ideas list wiki page](https://gitlab.gnome.org/jrb/crosswords/-/wikis/ideas). It consolidates the ideas from three documents of mine: * The printing ideas from my GSoC proposal. * The word score / outreachy ideas document. * The ideas document I made at the start of GSoC, when we were deciding what I should work on. ### 2025/October/29 * Editing forward checking doc. * I think it is not possible or correct to not mention the intersection algorithm at all, in this doc. I think comparing the two is needed, in order to highlight the benefits of the forward checking algorithm. * Editing AC-3 doc. * Regarding the resources section: * I think the only learning resource that's needed is the course notes I recently found. So I will set that as a link, and remove the learning resources section entirely. It is not particularly hard to find more resources anyway. * For the miscellaneous resources, I think the wiki is a better fit than this design doc, so I am removing it as well (and creating a new wiki page). ### 2025/October/28 * Started editing forward checking doc. ### 2025/October/27 * Responded to review comments. * Edited intersection function doc. ### 2025/October/26 * Working on splitting up the doc: * I do think we should use "forward checking" instead of "lookahead." It isn't like the term "lookahead" is used in 50 different files and docs or anything. So I think it should be simple to change. * Problem: if we split up the 3 different word suggestion algorithms into their own docs, then we no longer have a good place to introduce what the word algorithm is, in the first place. * Solution: create a document for word suggestions in general that does a brief introduction of what the word suggestion list and algorithm is. Potentially, this document could include a short comparison of the three algorithms, pros and cons, etc. Maybe also mention the crossword aids stuff and link to that doc. So this `word-suggestion.md` document could serve as a central document that links to and introduces the other documents. * We also need a place to put my glossary. I think I will just turn it into the main glossary file. I also saw a small glossary in `word-entry.md`, so I'll merge mine with that. * I think a comparison table in central document is a good idea: speed, input/output (clue vs grid), dead-end words. * Central doc should also explain that the lookahead algo uses the intersection algo, and that the intersection algo was superseeded by the lookahead, etc. That way, the individual docs can avoid mentioning anything about each other, which would be messy. * I will try to get an MR in as soon as the docs are split-up, and before editing the docs much. That way, we can make sure we're on the same page regarding how the docs are split up. * Right now, just having the intersection-based algorithm in its own doc, it already feels much nicer to read. It explains the algorithm, and then the limitations. Feels much better than before. I don't think I need to change the texts much either---I think what I've written mostly works by simply moving the parts into their own docs. * Created MR for docs split-up. ### 2025/October/24 **Talk with Jonathan** * Can use asterisk to say we're using lookahead instead of forward checking. * Caching is straightforward for AC-3, you just keep a state of all the constraints, domains, etc., and update it whenever the grid changes. * Caching for lookahead would be more interesting. Caching sort of moves it towards AC-3. * Lookahead is fast-ish, as it is. * I think if we never plan on implementing AC-3 (and all the crossword aids that come with it), then it could be worth looking into doing caching and squeezing out some extra performance. * Important goal of AC-3 design doc is: what features will we get out of it? * Once we have the three docs, it should be clear how they relate to each other and how AC-3 compares with and differs from lookahead. * Probably don't want any inter-dependence between docs. ### 2025/October/23 * Added CSP notes and sub-alphabet notes to wiki. * I think a big problem with the current design doc is how coupled together all the different parts are. Like even if we pretend like they are separate documents, the way it's written is still too inter-dependant. * So I think a big goal of the split-up is to make all the parts mostly independant, except for like a "For the X approach, see here" that links between docs. * The general split-up I am thinking of is this. (And each category could be multiple docs, but I think these are the main categories that we want. And the categories should be very independent from each other. But within each category, if there are multiple docs, it's okay for them to be coupled and form a sequence): * Intersection function * Lookahead approach * AC-3 approach * Submitted issue for test script variable. * Helped user with test failures in Matrix chat. ### 2025/October/22 * Looked into Sebastien's sub-alphabet idea. Basic idea is: 1. Reduce the word list with a character mapping function. * Most extreme exampe is `Vowel -> V, Consonant -> C`, but can also use less extreme mappings like `Vowel -> V, QXZJK (rare letters) -> Q, Everything else maps to itself (identity function)`. 1. Find possible "words" (really, patterns) for a given slot, by using this reduced word list. * For example, a three-letter slot might have *CVC* and *VVC* (not actually true). Then, we know that any word that fits in a three-letter slot has to match either *CVC* or *VVC*. No word exists with three consonants in a row, for example. 1. Reduce the original word list by only keeping the words that match the patterns we found in step 2. * So for example, we reduce the word list to only have the words that match either *CVC* or *VVC*. 1. Run the standard word suggestion algorithm on the reduced word list. * My thoughts: * Unsure if this would actually be faster in the end. Sebastien says: "Trying a lot of faster solving with additional constraints **may be faster** than crawling the full search space" * I haven't seen anything like this in any of the crossword CSP papers I looked at. If it did exist somewhere, then we could be more sure of its potential benefits. * I think some of our other ideas, like caching or AC-3, have more guaranteed benefits, whether in terms of accuracy or speeds or enabling crossword aids. * So I would say this sub-alphabet idea is good to keep in mind, but not a high priority to implement. ### 2025/October/21 * CSP / AC-3 reading. * I have a better understanding of some terms and ideas that I previously was not so sure about: DFS (as a CSP algorithm), backtracking search, lookahead, forward checking, heuristics. * I think these were the main things that I wanted to clarify, when I stopped, last time. * So the CSP / AC-3 reading should be done now. Next steps: * Look into Sebastien's suggestions. * Start making changes to design doc. * Also, I've found a [much better resource](https://inst.eecs.berkeley.edu/~cs188/textbook/csp/csps.html) for the CSP stuff, compared to the lecture slides that I previously used. So I will update the design doc's resource list to probably only include this. Maybe one or two others, if they offer things that are missing form this one. ### 2025/October/20 * CSP / AC-3 reading. ### 2025/October/19 * CSP / AC-3 reading. * Terminology note: *Lookahead algorithms* includes both *forward checking* and *AC-3*. Our word suggestion algorithm is a forward checking algorithm. So it would be more precise to refer to it as a *forward-checking algorithm*, though that is quite a long name. ### 2025/October/19 * CSP / AC-3 reading. * [New pad for CSP notes](https://pad.gnome.org/s/vNYCDoL5S) * I'm going to avoid adding anything about the autofill algorithm, because that is a big enough topic on its own, and I want to keep the scope under control. ### 2025/October/18 * CSP / AC-3 reading. ### 2025/October/16 * Regardless of what we decide on Friday, I think it might make more sense to add all the WIP parts to the existing docs *before* splitting it up. * Having all the finished parts should make it easier to decide how to split it up. ### 2025/October/15 * Thinking about how to split up the doc. * Here are the topics currently covered by my doc: 1. Glossary. 1. How the `word_list_find_intersection()` function works. 1. Limitations of using the intersection function as our word suggestion algorithm. 1. The lookahead-based word suggestion algorithm. 1. Limitations of the word suggestion algorithm. 1. How to express grid filling as a CSP. 1. The AC-3-based word suggestion algorithm. 1. AC-3 and CSP resources. 1. A comparison of the lookahead-based and AC-3-based algorithms. 1. It's possible to turn the lookahead-based algorithm into a grid-level algorithm, but it's probably not a good idea. 1. Prior art. 1. Implementation for the lookahead-based algorithm. * Here are the potential topics to add: * Applications for grid fill algorithm. * Caching. * UX for the AC-3-based algorithm. * Hybrid implementation. (Use lookahead for sparse grids, AC-3 for dense grids.) * ==Potential way of splitting up the doc:== * General document for word suggestion algorithm that gives a small introduction and ties all the documents together and links to them. (Maybe.) * Intersection function explanation + its limitations as a word suggestion algorithm * Lookahead-based algorithm explanation + implementation. * AC-3-based algorithm explanation. * AC-3-based algorithm UX ideas. * Crossword aid ideas. (Merge with above?) * I think anything having to do with the UX of the AC-3-based algorithm (settings, aids, UI, etc.) is not too important, because there are no immediate plans to implement the AC-3-based algorithm in the first place. * The lookahead-based algorithm and AC-3-based algorithm explanation (minus any UX discussion) is far more important. * However, since I've thought about the AC-3 UX for a while now, I still want to get all my ideas down. But I think it will look more like a rough list of notes and ideas, rather than a polished doc. * Best to discuss this all on Friday, I think. I'll start digging deeper into the AC-3 stuff for now. ### 2025/October/14 * Finished blog post. (Publishes on Wednesday.) ### 2025/October/13 * Writing blog post. ### 2025/October/03 **Jonathan Update:** * Looked at MRs. Merged 3/4. Next week is off * After that, blog post and clean up design doc * We're ready from Victor for the release. * [ ] Victor move those files then we merge last MR * [ ] Jonathan: go through Victor's doc suggesions. ### 2025/October/02 * Opened MR for separate `WordArray` and `WordSet` files. * Opened MR for improving the print functions. ### 2025/October/01 * Tested the set intersection optimization. It's not any faster. Here are the results, with 30 runs per test: ``` With the set intersection optimization: ************************************** * PERFORMANCE TESTS RESULTS * * * * Combined runtime: 0.968480 seconds * * Average runtime: 0.088044 seconds * ************************************** Without the set intersection optimization: ************************************** * PERFORMANCE TESTS RESULTS * * * * Combined runtime: 0.943512 seconds * * Average runtime: 0.085774 seconds * ************************************** ``` * Tested the skip phase 3 optimization. Looks like it is a bit faster! ``` With the skip phase 3 optimization: ************************************** * PERFORMANCE TESTS RESULTS * * * * Combined runtime: 0.790712 seconds * * Average runtime: 0.071883 seconds * ************************************** Without the skip phase 3 optimization: ************************************** * PERFORMANCE TESTS RESULTS * * * * Combined runtime: 0.952440 seconds * * Average runtime: 0.086585 seconds * ************************************** ``` * Started refactoring `word-list-misc.c`. ### 2025/September/30 * Opened MR for performance tests. ### 2025/September/26 * Submitted issue for error messages popping up when you close the editor. * Finished adding test crosswords for performance testing. * Miscellaneous improvements to performance testing. * I'm trying to get an average runtime of all the performance tests. I think to do that, I need to have a separate fixture specifically for the performance tests. Talk with Jonathan: * File bug for improving word score alignment, newcomer tag. * Look into the issue I had about the conversion. * Code stuff: 1. Finish performance testing MR. 2. Test the two optimizations and MR for them if needed. 3. `WordArray` and `WordSet` in their own files + new print functions. 4. Blog post after all the code stuff is done. * Jonathan will debug the error messages problem. * Docs notes: * Build instructions: * Move flatpak section below container build but before local build, since it's less ideal for development. * Codebase: * If you do decide to keep it, add a warning at the top that some parts are not up to date, like what we have in the design docs * Editor doc could use the [wiki doc Victor did](https://gitlab.gnome.org/jrb/crosswords/-/wikis/guadec-notes). * Naming disambiguation, Victor found it really uesful when learning the codebase, like "this function is in this other file, what is that file for and how is it different, like puzzle-set vs puzzle-set-model". Worth updating. * When updating, there will be many more files. I think a flat structure makes it harder to read. I think using lists and sublists (like simulating a directory structure) would be good, to visually group related files together. * Actually, I guess that's sort of what you already have with headings and subheadings. * As a potential alternative, and maybe it looks better maybe not, you could use sublists: ``` ## Player ... ## Editor * Acrostic * `acrostic-answer-list.c` * `acrostic-generator.c` * ... * Color * `edit-color-row.c` * `color-palette.h` * `edit-color-swatch.c` * ... ``` * Add a note about complexity being concentrated = certain files do/touch a lot of things; but most widgets are self-contained. * Maybe a general philosophy of crosswords doc. * For the crosswords player doc: I did find it useful to have some things like puzzle picker, puzzle set explained. I think I realized that the doc doesn't cover everything, rather more just a few things explained. I would just add a note at the top saying some things are missing. * General recommendation: Keep any information that may be useful, even if it is incomplete or somewhat out of date; just make that clear at the top of the file. * Libipuz general: * API docs are really useful for learning, should make them more visible. * In README, can give them their own section, and move the two links to that section. * In the non-API libipuz docs, can add a big bold link at the top like "API docs here," might be useful. * For the API docs, it would be good if there was one introduction doc that sort of summarizes how all the pieces / classes fit together; sort of like the "naming disambiguation" in crosswords docs. It would contain information like: * The class heirarchy: `IpuzPuzzle -> IpuzGrid -> IpuzCrossword -> (IpuzAcrosstic, IpuzCryptic, etc.)` * How other classes relate to one another, like `IpuzClue`, `IpuzCell`, `IpuzCellCoord`, etc. * How to do basic/common tasks, like I have a grid and I want to get all the clues; [stuff like this](https://libipuz.org/libipuz-1.0/class.Crossword.html#clues), but maybe in the introductory document, so it's all in one place. * Generally: I think whether you should improve the libipuz docs vs. crossword docs depends on how much you expect new contributors to have to use libipuz stuff. Like if they are working on the UI or higher-level things in the crosswords codebase, then maybe they don't even encounter the libipuz code much. * Thoughts on naming: * It is maybe impractical to change this now, but there are two naming things that confused me a lot when I started. And I think the current naming is just incorrect. * I think it would be benefitial to make these naming ambiguities clear in some doc. * The term *clues* to refer to the slots of a grid. * It is an ambiguous term, because *clue* also refers to the hints for the different slots. * An example of the problems with this ambiguity is the function `ipuz_clue_get_clue_text()`. It's hard to understand from the name, what it does. Is it getting the guess that the user entered? Or the solution to a slot? Or the hint to a slot? * I think it is also just incorrect to call a slot a clue. Because a clue is the hint for a row/column in a crossword puzzle; it is not the row/column itself. *Slot* seems to be the most common term I've seen from other editors. * The term *word list* is also used in multiple different ways. * It could refer to: * The dictionary of possible words to suggest (e.g. the broda word list). * The `word-list.c` file. * The `WordList` class. * The precompiled `GResource`. * The word suggestion list. * Potentially: the upcoming *libwordlist* library. * In an ideal world, I would recommend something like this: * *Word list* = dictionary of possible words. * *Word list resource* = the `GResource`. * `WordList` ⟶ (rename) `WordListResource` maybe? The idea being that you have the `GResource` itself, which is the *word list resource*. And then you have the `WordListResource` class, which uses the *word list resource* to do useful things. * *Word suggestion list* = the UI element. * `EditWordList` ⟶ (rename) `WordSuggestionList`. ### 2025/September/25 * Finished basic code for performance tests. Just need to come up with the IPUZ files to test. * Added option to assert that a performance test runs within a given time limit. ### 2025/September/24 * Opened MR to add another macro to `clue-matches-tests.c`. * Finished adding new tests. Will wait for the new macro MR to be merged, because the new tests depend on it. * Opened MR for new tests. ### 2025/September/23 * Opened MR to improve `word_array_print()`. It was getting annoying, trying to add new tests to `clue-matches-tests.c` and not having an easy way to figure out what's wrong, when a test I write fails. ### 2025/September/22 * Started creating more tests * Opened MR to reduce boilerplate in `clue-matches-tests.c` ### 2025/September/19 * Ok, the segfaults are caused by me using `g_autofree` on the `IpuzClue`, inside the function that does all the testing. So if I call the same test twice, then the second time, the clue is already freed, which is what causes the segfault. * I suspect this may also be the cause of all the strageness with the CI failures. * Actually yeah, that would make sense. Because I do the across clue first; then it gets freed; then when the down clue gets to the freed horizontal clue, it contains garbage data. * [Yup...](https://gitlab.gnome.org/vic-ma/crosswords/-/commit/a1f0cf119090d9fe6fe02af43909fae7ccbb16ed/pipelines?ref=refactor-tests-y) * MR ready. ### 2025/September/18 * Segfault issue: * Happens when I repeat the same `word_list_get_clue_matches()` call twice in a row, within the same test function. * The segfault happens in `ipuz_clue_get_coord()`, on a specific iteration of the lookahead for-loop. `ipuz_clue_get_n_coords()` also causes a segfault. * I also get a segfault if I call `ipuz_clue_get_n_coords()` at the start of the lookahead function. * The segfault happens inside this rust function, for the get n coords case: * ``` #[no_mangle] pub unsafe extern "C" fn ipuz_cell_coord_array_len(array: *const IpuzCellCoordArray) -> usize { println!("Hello, world!"); ipuz_return_val_if_fail! { ipuz_cell_coord_array_len => 0; !array.is_null(), }; println!("Hello, world!"); let inner = (*array).lock().unwrap(); <-- segfault happens here println!("Hello, world!"); inner.len() } ``` ### 2025/September/17 * I used `ipuz_grid_foreach_cell()` to print out the grid, as a sanity check. And it is correct. * I've sort of figured out what's going on: * Recap: There's a cell that I try to get the intersecting clue for. And `ipuz_cell_get_clue` returns `NULL`, even though it shouldn't be. * Turns out, [both clues associated with the cell have a direction of *DOWN*](https://gitlab.gnome.org/vic-ma/crosswords/-/jobs/5551102#L3120:~:text=3120-,%23%20MESSAGE%3A%20%2D%2D%2DITERATION%20(1)%2D%2D%2D,%23%20MESSAGE%3A%20intersecting_clue%20%3D%3D%20NULL,-3129). * And the direction I'm looking for (the intersecting direction) is *ACROSS*. So the function returns `NULL`, because it can't find a clue associated with the cell that has a direction of *ACROSS*. * But on a local run, this is not the case. The first `cell->clue` has the correct direction of *ACROSS*. I also verified that the second clue is *DOWN*. * Actually, that's not quite right. Previously, I assumed non-across means down. But actually, when I print out the direction as a number, I get 4, which is some diagonal direction. * I also found that reordering the test calls within the `test_valid_intersections` (one tests the across clue, one tests the down clue) changes the results. And it looks like I even got my local test run to fail: ``` # MESSAGE: ---ITERATION (3)--- # ipuz_cell_get_clue: # cell->clues is not NULL. # cell->clues->len: 2 # Looking for: 2 # INDEX: 0 DIRECTION: 1 # INDEX: 1 DIRECTION: 4 # Returning NULL. # MESSAGE: intersecting_clue == NULL # END FUNC >>>>>>>>>> ``` * Also if I try to repeat the test calls within `test_valid_intersections`, I get a segfault. ### 2025/September/16 * Continue debugging the CI test failures **Jonathan's update** So, looked into it a bit. There's a definite slowdown when we use gtkbuilder. I'm talking to the GTK team about what this means to see what's going on. We may want to go back to building it manually. That being said, we're creating 200 widgets at a time for relatively small sets, which confuss me. Investigating more. **Update:** That didn't take long: `#define GTK_LIST_VIEW_MAX_LIST_ITEMS 200` ![Flamegraph with EditWordListRow](https://s3.us-east-2.amazonaws.com/hedgedoc-gnome-org/uploads/5f72bb85-a8ae-4970-8496-f51c110a97c3.png) ![Flamegraph with master](https://s3.us-east-2.amazonaws.com/hedgedoc-gnome-org/uploads/581a2417-36c9-4058-b7bd-5616384e031c.png) ### 2025/September/13 * Something funny is going on with my performance results, because even on master + blank grid, it's 30 ms. And I know I used to get 16 ms. * I also tried on commits from before the lookahead MR was merged, and same thing, ~30 ms. So it's something to do with my machine/container. * Gonna do a clean distrobox install and see if that fixes things. * But none of this changes the fact that my `align-scores` changes do perform worse than `master`. * It may be odd that `master` is at 30 ms on my machine now. But `align-scores` is still 5 ms above that. So I don't think this really changes much. * I created the branch `refactor-tests-x`, where I reverted all the changes to `edit-word-list.c`. So my row widget code should not be run at all. Here are the results: | Branch | Blank grid | Test grid | |------------------|------------|-----------| | `master` | 31 ms | 35 ms | | `align-scores` | 37 ms | 40 ms | | `align-scores-x` | 31 ms | 35 ms | * So we know that it *is* something about the row widget code that's causing the performance degredation. Next step: remove the blueprint. * Results from removing the Blueprint: | Branch | Blank grid | Test grid | |------------------|------------|-----------| | `ailgn-scores-y` | 35 ms | 38 ms | * Links to branches: * [`align-scores`](https://gitlab.gnome.org/vic-ma/crosswords/-/tree/align-scores?ref_type=heads) * [`align-scores-x`](https://gitlab.gnome.org/vic-ma/crosswords/-/tree/align-scores-x?ref_type=heads) (revert `edit-word-list.c`) * [`align-scores-y`](https://gitlab.gnome.org/vic-ma/crosswords/-/tree/align-scores-y?ref_type=heads) (remove blueprint file) ### 2025/September/12 * Code is done, but it's performing measurably worse than upstream. * Need to figure out what's introducing the extra delay. * The performance hit is not from any of these functions, because commenting them out doesn't affect the performance: * `combine_word_and_enumeration_src()` * `edit_word_list_row_update()` * `edit_word_list_row_dispose()` * `model_row_changed()` * `bind_listitem_cb()` * `unbind_listitem_cb()` **Update Checkin with Jonathan:** * Next steps on alignment slowdown: try swapping in a `GtkLabel` and see if that makes the performance problems go away. If so, we should try eliminating the UI file. If not that, ping jrb and he'll debug. * Also, keep looking at the test failures. Let's try to land that. Jonathan has no time this weekend to debug, but possibly next week if victor is still stuck * Keep working on he AC-3 design doc * Good luck on job search! Feel free to send me a resumé ### 2025/September/11 * Finished changing `EditWordList` to use `EditWordListRow`. ### 2025/September/10 * Made changes to `EditWordList` to use `EditWordListRow`, but the `Box` and `Label` are not showing up in GTK Inspector. * Opened draft MR for review. * Edited comments in `clue-matches.c`. * Flatpak issue: * Now I'm seeing the `build-and-test` job having a test failure, even though local tests are still passing, even with a clean build. * But before looking into it further, I need to first fix the CI config to upload log artifacts properly. It looks like the path is wrong/outdated for a couple of the jobs, including the `build-and-test` one. * Opened MR for CI fix. ### 2025/September/09 * Got the score align code compiling. * Trying to plug `EditWordListRow` into the `EditWordList` factory methods. ### 2025/September/06 * Investigating flatpak CI failure. * It should be using broda. I printed the resource path right before the `WordList` is created, and it is broda. * I've tracked the problem down to the unch-skip code. The CI thinks the intersecting cell is an unch (it's not). * Trying to do flatpak install locally. * Doesn't seem to work inside distrobox. * Stuck at: ``` ... error: Requested extension org.freedesktop.Sdk.Extension.rust-stable/x86_64/48 not installed Error: Child process exited with code 1 victor@debian:~/crosswords-mirror$ flatpak install org.freedesktop.Sdk.Extension.rust-stable/x86_64/48 Looking for matches… error: No remote refs found for ‘org.freedesktop.Sdk.Extension.rust-stable/x86_64/48’ ``` ### 2025/September/05 * Tried sysprof. * Doesn't look like sysprof works inside distrobox container. * But I can run sysprof on my host OS, run `crosswords-editor` inside the container, and `crossword-editor` does show up in the sysprof recording. * But I can't find the individual functions in the flamegraph. * So I think the fact that `crossword-editor` is running inside the container is messing up the profiling. * But I can also try running everything inside a VM, and that might work properly. I'll leave that for when I'm profiling the two optimizations. * Starting on the word list alignment task. * Read GTK list widget docs. * Looked through our current code. I think I understand how the factory callback functions work now. * I need to create a new `EditWordListRow` widget, and plug it into the callback functions, replacing the label widget. * Getting stuck on all the GObject boilerplate code. I roughly copied what `edit-word-list.c` has, but I'm getting compilation errors. [Link to my changes.](https://gitlab.gnome.org/vic-ma/crosswords/-/compare/master...align-scores?from_project_id=16742) Next steps: * [x] Debug the flatpak test failures. * [x] Finish the word score alignment. * [x] Add more clue matches tests. * [x] Add clue matches profiling test. * [x] Profile the two optimizations to see if they're faster. * [ ] Blog post. (Reflection?) * [ ] Design doc. ### 2025/September/04 * Opened MR for better test asserts in libipuz. * Add toctree to libipuz. ### 2025/September/03 * Opened MR for better test asserts in crosswords. * Started work on better test asserts in libipuz. ### 2025/September/02 * The test refactoring is done. But for some reason, the test fails in the CI pipeline. * Can try debugging further, but it's a slow process. So I'll first wait for a review from Jonathan to see if he has any ideas. * Going to work on non-test-related issues for now, since the test issues will depend on the refactoring. ### 2025/September/01 * Add fixture code. ### 2025/August/30 * Small fixes and filling issues. ### 2025/August/29 * Start refactoring tests. * Miscellaneous small fixes. **Checkin with Jonathan** * Nice work on optimizing the intersection code and the blog * Jonathan has 5 MRs to review, but don't look terribly controversial * Next: * [x] Add a few more tests (unit, not profile) * [x] When ready, libipuz sphinx setup * [x] Play with sysprof a little * [x] Refactoring the tests for a common setup procedure * [ ] Add a profiling test * [ ] After this, design doc clean up for lookahead * [ ] Finish up the AC3 section * (Jonathan still owes a doc on async code) * [ ] Figure out if the optimizations are actually faster * Smaller issues afterwards: * [x] Label Alignment bug * [x] Don't take duplicate words into account. Should look into that? file a bug * [x] file a bug for the custom size bug * [ ] Font thing might be interesting? * [ ] Hotspot detection design doc? * [ ] Requires AC3 algorithm implementation * [ ] Caching results might be interesting as well, may come out of the AC3 master plan ### 2025/August/28 * Figured out the problem with the "skip phase 3" change that I did a while ago. Fixed the problem. * It seems like the optimized version performs better? But just like with the set intersection optimization, I'm not too confident in saying this. * Because the way I've been testing the performance is opening the same test IPUZ file I made, and then repeating the same cursor movements. * For both optimizations, it seems to me like they outperform the unoptimized code more often than not. But there are times where the unoptimized code performs better. * The optimizations logically make sense, so I want to say that the times where they perform worse are just outliers, caused by whatever cursor movements I happened to do for that test run. * But that's not very assuring. So here's my plan: * Both optimizations are currently finished (skip-phase-3 and set-intersection). * Hold off on the optimization MRs for now. * Finish the FIXMEs for `clue-matches-tests.c`, which includes adding a profiling test, like what we have in `word-list-tests.c` * Once that's done, use the profiling test to check the performance of the two optimizations. * Opened MR for common test utils ### 2025/August/27 * Finish blog post (publishes tomorrow). * Start working on making intersection function's phase 3 optional. ### 2025/August/25 * Work on failed-optimization blog post. * Was going to add performance stas for both "optimized" and unoptimized---but it's not as easy as I thought to re-impliment the optimization that I had. So I'm just going to skip it. * Nevermind, I was able to fix the code. * But I'm not really seeing the same performance results as I did last time. * It looks like sometimes the performance is equal, but sometimes the optimized version is actually faster. It used to be either the same or slower. * Worth looking into further. ### 2025/August/24 * Work on blog post. ### 2025/August/23 * Work on blog post. ### 2025/August/22 * Add links to wiki and libipuz docs. * Fix Sphinx warnings. ### 2025/August/21 * Finished printing doc. * Moved pads to wiki. * Opened MR for `toctree`. ### 2025/August/20 * Work on toctree. * Work on printing doc. ### 2025/August/19 * Work on toctree. ### 2025/August/18 * Start working on requested changes for lookahead MR. ### 2025/August/16 * Use colons instead of backticks, for admonitions. ### 2025/August/15 * Submitted admonitions MR. * Started working on adding `toctree` to the docs. * Some pages have multiple top-level headings, which I need to resize, in order to not have the table of contents look weird. **Jonathan Checkin** * Good work on the MR! great stuff * [x] Jonathan to review the code this weekend. Suggested a name change for victor to use. Target by Monday * [x] Victor to update the admonisions MR, and jonathan will land it * [x] Victor to work on the toc changes Next: * [x] Fix sphinx warnings * [x] Right align score warnings — ask jrb for advice as that shouldn't take long * [x] Sphinx autobuild * [x] Can Victor do a survey at print dialogs options * [x] Jrb to ping n8 again to get font feedback ### 2025/August/14 * Rebased MR and made some final changes. * Submitted MR. ### 2025/August/13 * Rebased and cleaned up code in preperation for MR. * Opened MR for `gtk_filter` renaming. * Submitted issue for key presses not working after selecting first word suggestion. ### 2025/August/12 * Fixed the loop. Now, there's an initial intersection call that always runs, right before the loop, and that only considers the current filter. It creates the initial set with this. * In case the loop skips all the cells, then this initial set is correct. * If the loop doesn't skip all the cells, then the set is just refined over time, as normal. * I have the basic test structure working now. It checks the `WordArray`'s length and contents. * I have three basic tests done now. After the MR, I want to add more + do some refactoring there + add performance measuring code (I saw that `word-list.c` has this). * Now, I will rebase onto `master`, fix any conflicts, and do the final testing for the MR. * Looks like no merge conflicts. ### 2025/August/11 * Clean up test code. * The for loop is too prone to problems stemming from the following requirements: * Handle the special cases where we can potentially skip the intersection calculation (unch and filled-in cell and empty intersecting clue) * Always run the intersection function and set creation code at least once. Otherwise the return set will be empty. For example, if we have a clue with all unches, we can't just skip every cell, because then the function returns the empty set. * Keep track of the current offset. This on its own feels error-prone. But the alternative is to calculate the current offset on each iteration of the loop, which is less performant. * I think the solution is to move the initial set calculation to before the loop. This simplifies the logic inside the loop. Maybe I can put the intersection + set creation code into a function, to avoid having duplicate code outside and inside the loop. ### 2025/August/10 * Created new test files. * Moved some common test funcs from `word-list-test` into a separate file. * Plan is to use `load_state (file, GRID_STATE_EDIT)`. * Didn't realize this existed. Thought I had to make the `GridState` by hand. I think I can be a little more comprehensive with the tests than I was planning. Still small grids though. * Creating test IPUZ files. * Assertion error when cursor is on black/null cells. Causes crash, so it needs to be fixed before the MR. * Having trouble building test file properly. Reverting all non-essential changes and trying again. * `word-list-tests.c` is failing, after the change where I made phase 3 optional. * Reverted commit for phase 3 change. Will do that after the MR. * Assertion fail fixed. Just needed to move the direction check up a bit, before the call to the asserting function,`ipuz_clues_get_clue_by_id`, is made. * Found and fixed another assertion fail caused by unches not being handled properly. * Ok, I think I have the meson config working now, for my tests. ### 2025/August/07 * [Refactor `edit-word-list.c` to get rid of dead code.](https://gitlab.gnome.org/vic-ma/crosswords/-/compare/b93b0e33e3de9b619a38d6e3559a0f2049d89791...6ea8a2e8a7c923444a32f1b59e529597f798bec0?from_project_id=34488) * Some code can be refactored, because the lookahead function only needs the current clue, unlike the intersection function. * Some code can be refactored, because we only show suggestions for one direction now. This should've been done when I made that change. But it's relevant now, so I'm doing it here. ### 2025/August/06 * Added optimization for intersecting filters that are completely unrestricted (e.g. `??????`). * For these filters, we can entirely skip the the intersection function call and the set intersection calculation. * This leads to significant performance improvements on an empty grid. The speed is about the same as upstream, or at least it feels that way. * Of course, this doesn't speed up the case where the current clue is parallel to a filled out clue. Those are still really slow. * Another optimization: Skip phase 3 of the intersection function. It's not really noticable, but there's definitely a small performance boost. Some stats from two runs, where I made the same cursor movements on the same grid: ``` WITHOUT OPTIMIZATION update_all(): Average time (15.233 ms) Longest time (45.927 ms) Total iterations (79) Total number of iterations longer than one frame (30) Total time spent in this function (1203.419f ms) word_list_find_intersection(): Average time (1.187 ms) Longest time (6.665 ms) Total iterations (396) Total time spent in this function (469.857f ms) --- WITH OPTIMIZATION update_all(): Average time (13.621 ms) Longest time (45.903 ms) Total iterations (76) Total number of iterations longer than one frame (27) Total time spent in this function (1035.203f ms) word_list_find_intersection(): Average time (0.774 ms) Longest time (4.651 ms) Total iterations (388) Total time spent in this function (300.163f ms) ``` * Tried another optimization: * Currently, the set intersection function always removes elements from the function-scope possible words set. * That is to say, it always iterates through each of the words in this set, and checks if it appears in the intersecting word set. If not, it removes it from the function-scope set. * The intersecting word set is scoped to the for loop, and is deleted after each iteration. * I imagined a scenario where the function-scope set has a bunch of elements, but the intersecting set only has one word (because the clue is very constrained). * In that case, each of the function-scope set's elements has to be checked and removed. * If we could instead check the intersecting set's single word, and then set that list as the function-scope set---then it would be a lot faster. * Well, that's what I thought. But in practice, it looks like doing this is actually either slower or makes no difference. * Exit early if direction is not across or down. ### 2025/August/05 * Looked into [`sphinx-autobuild` issue](https://gitlab.gnome.org/jrb/crosswords/-/issues/294#note_2513946). Currently stuck, so going to leave it alone for now. ### 2025/August/04 * Handle rebus in current and intersecting clue. * Added [blog post 6](http://victorma.ca/posts/gsoc-6/) (set to publish tomorrow). ### 2025/August/02 * So the memory allocation bug was: 1. `WordSet` has keys that point to the elements in a `WordArray`. 1. I free the memory for `WordArray` before the `WordSet` is done being used. 1. The keys in `WordSet` become dangling pointers. 1. Some of the memory blocks in the now-freed `WordArray` are overwritten and now contain garbage data (appears as `AM (80)`). However, others have not yet been overwritten, and so they just so happen to still contain the original, valid data. * This is the thing I was confused about---why don't *all* the blocks have garbage data? But after some more testing, I can see that it's random how many of the word suggestion list entries are invalid. * Originally, I thought it was always just two or three invalid entries. Now, I realise that that is not the case. Sometimes, most of the words are invalid; sometimes only a few. * So this makes sense to me now: it's just random chance that certain memory blocks in the freed `WordArray` still contain valid data. * More small fixes. ### 2025/August/01 * More code cleanup and refactoring * Investigating `WordArray` memory allocation bug. ### 2025/July/31 * Fixed some memory management code ### 2025/July/30 * Lookahead function is working now. * Clicking around on an empty *large* grid: ``` 📦victor@box:~/crosswords$ ce MESA-INTEL: warning: ../src/intel/vulkan/anv_formats.c:940: FINISHME: support YUV colorspace with DRM format modifiers MESA-INTEL: warning: ../src/intel/vulkan/anv_formats.c:972: FINISHME: support more multi-planar formats with DRM modifiers ^C Targeting 16.67 ms for a frame update_all(): Average time (92.888 ms) Longest time (179.208 ms) Total iterations (19) Total number of iterations longer than one frame (19) Total time spent in this function (1764.863f ms) word_list_find_intersection(): Average time (2.104 ms) Longest time (7.385 ms) Total iterations (630) Total time spent in this function (1325.611f ms) ``` * We definitely still need to do it asynchronously---but even synchronously, it's far from unuseable. There's a < 1 second delay when you move the cursor. And that's on an empty grid. * This also shows how much faster this lookahead approach is, compared to grid-level algorithms, which some other editors use. For those editors, on an empty grid, the initial load of the algorithm never completes. On a sparse grid, it still takes several seconds. * So this supports the idea that the choice between lookahead and AC-3 is a choice between speed vs. accuracy---and that it could make sense to implement both, and let the user decide which one to use, or automatically change which one is used. For example: ``` empty grid -> return all words equal to length of clue lightly filled -> intersection function OR lookahead moderately filled -> ac-3 ``` * And now that I think about it, it's probably not possible to turn lookahead into a grid-level algorithm. One of the default large grids has 75 across clues and 68 down clues. Even assuming the grid is somewhat filled and the lookahead function takes an average of 0.1 seconds to run, that's still 14 seconds total. * The AC-3 algorithm is definitely more well-suited to the task of scanning the whole grid. So if we want the crossword aids, we probably need to implement the AC-3 algorithm. * **Next steps:** * Code is pretty messy right now, after all the debugging I did to get it working. Need to free memory properly, refactor some code, and make my `word_set` functions more complete, since I now have `typedef GHashTable WordSet`. * Write blog post showing that the problematic grid works now, and discussing the performance of the lookahead algorithm. ### 2025/July/29 * Finished `get_clue_offset ()`. * Intersection function call is working. ### 2025/July/28 * Moved lookahead function into its own file. * Added `clue_to_filter ()`. * Tried moving intersection function out...got lots of errors. Probably needs lots of refactoring to work. Going to leave the function inside `word-list.c` for now. * Started `get_clue_offset ()`. ### 2025/July/27 * I've finished coding the loop that iterates through the intersecting clues. * Next step: Add a function to `word-list-misc.c` that transforms an `IpuzClue` into a filter string. Then, I can pass that into the intersection function. * Other things: * Need to handle early-return cases, like block cells and unches. * Does rebus handling work properly? * Will try to move the lookahead function outside of `word-list.c`. ### 2025/July/25 * Trying to get a reference to the current clue: * `GridState` has a reference to the current clue: `IpuzClueId clue`. * So my lookahead function needs to have access to `GridState`, or the caller needs to have access to `GridState` and pass in the `IpuzClueId`. * Actually, `IpuzClueId` are not guaranteed to be stable, so I can't use it. * So instead, I will use `GridState.cursor`. Just need to convert it into an `IpuzClue`. * Added code up to the point where I have the intersecting clues in the loop. * Need to have access to the `GridState` object, so I can get the intersecting clues. * Can't seem to add headers without getting a compilation error. ### 2025/July/24 * Started working on lookahead sync implementation. * Trying to figure out the best way to get the current clue, so I can access the intersecting clues. * The current intersection function takes the filter strings directly; it doesn't get any coordinate information. * Realized I need to look in libipuz. * Roughly: 1. Get current cell and direction with ??? * Does `EditWordList` have access to cursor information? 1. Transform into current clue with `ipuz_cell_get_clue` 1. Transform into coords of clue cells with ipuz_clue_get_coords 1. Transform into cells with ??? 1. Get intersecting clues with ipuz_cell_get_clue ### 2025/July/23 * Finished [response to Sebastien](https://pad.gnome.org/s/tjTRe2d5H). * Can reuse parts of the response in the design doc. ### 2025/July/22 * Writing response to Sebastien. * Looking into how the word solver works. ### 2025/July/21 * Use proper admonitions? * Finished final edit and opened MR. * Messaged Sebastien. * Submitted some docs-related issues. ### 2025/July/20 * Doing final edit of design doc. * Got LaTeX working for our docs. Just need to modify the configuration file to enable a MathJax extension. * Enabled word wrap for table cells. * Thought of some docs-related tasks: * Add a version of `gen-devel-docs.sh` that uses `sphinx-autobuild`, for live reload. * Document how to build docs. * Add TOC tree to fix warnings and have better sidebar navigation. ### 2025/July/18 * Gonna do one last edit, and then open an MR. The AC-3 related parts are not fully done, but they're not relevant to the lookahead approach anyway. * That way, I can start coding. And then I'll gradually finish the AC-3 parts over time. * I've commented out the WIP parts. * Model $m_2$ in [this paper](https://cs.uwaterloo.ca/~vanbeek/Publications/cai01a.pdf) uses binary constraints for word uniqueness. So that should work? Adding it for now. * There may also be a generalization of AC-3 that works for $k$-ary constraints. Maybe that's another option, though transforming into binary constriants is probably the better bet. > **Jonathan Update:** Fantastic work on the design. > Some updates: > * Jonathan is going on Vacation/GUADEC for 2 weeks starting tomorrow. Next two Friday meets are probably canceled, though Jonathan will try to keep in touch, as Victor will start coding soon. > * [ ] Victor to land a design doc against `master` > * [ ] /CC sebastian, federico, Tanmay, and I, and I'll be reviewer. > * Three questions for the design to answer up top: > * How is the user experience going to manifest? Can we run fast enough to be syncronous? Answer can be probably not, but call it out > * Can we cache results or do this incrementally? Maybe, but let's focus on landing the naïve approach first > * What is the API for the word-list.h > * Another issue, let's right align the word score > * File an issue for adding latex plugin for sphinx and see if we ccan get that to render > > Goals for 2 weeks from now: synchronous look ahead implementation ### 2025/July/17 * The stuff related to the lookahead approach is done now. * Doing more research into AC-3 to flesh out those parts some more. ### 2025/July/16 * Problem: AC-3 algorithm only works for unary and binary constraints. So it can't handle the n-ary *no duplicates* constraint. * Potential solution: transform the n-ary constraint into $n^2$ binary constraints. * But figuring out every bit of the AC-3 approach isn't necessary right now. The only point of the AC-3 section is to say *this is another possible approach*. * I'll look into it a little bit, but then focus on finishing the rest of the doc. * Added approach comparison section. * Added prior art section. * Added implementation section ### 2025/July/15 * Went through and edited the whole design doc. ### 2025/July/14 * Published [blog post 5](https://victorma.ca/posts/gsoc-5). ### 2025/July/11 * Continued working on lookahead design doc. * Mostly finished with AC-3 parts. * Created [CSP resources](https://pad.gnome.org/s/I7xOv-9wN) document. ### 2025/July/09 * Continued working on lookahead design doc. * I now have a pretty good idea of how the AC-3 algorithm works and how we could use it. * Started writing sections explaining this. * I think the AC-3 stuff should go in its own design doc—just without the implementation sections, etc. * Even if we go with the lookahead approach, there is a future where we make both the lookahead algorithm and AC-3 algorithm available for the user to choose from (fast vs. slow). * Or a future where we replace the lookahead approach with the AC-3. * The AC-3 algorithm can also be used to implement a manual *check grid* function. This is sort of a comprimise between the responsiveness of the lookahead method and the accuracy of the AC-3 method. The user presses the *check grid* button to run the algorithm and get: * An accurate set of word suggestions for every slot. * An accurate fillability indicator. * An accurate heatmap. * An accurate *jump to most constrained slot* function. * I will discuss these possibilities in more detail in the design doc / next call. * Even if we decide to never use AC-3, I think the separate AC-3 doc is good to have because: 1. It doesn't really fit in the lookahead doc, whose whole purpose is to say, *we're doing this lookahead approach and not AC-3*. 2. It's useful to have a design proposal that says *yes, we've considered this option, and no, we are not going to implement it, for X, Y, and Z reasons.* So kind of like a *deprecated* tag, but instead, it's *not planned*. ### 2025/July/09 * Continued working on lookahead design doc. * Looked into open source editors' word suggestion algorithms * Exet does not appear to have any lookahead, despite what they claim. * Ingrid uses the AC-3 algorithm, combined with a backtracking algorithm. Their code is well-documented. * Didn't look too much into Qxw or Crosshare, but they do both implement a grid-level algorithm, like Ingrid. * I don't think digging through the source code of different editors is efficient or useful. * So instead, I started reading about CSPs and the AC-3 algorithm. ### 2025/July/08 * Continued working on lookahead design doc. * Started work on sections explaining why one level of lookahead. * Went back and forth a bit on how to structure that part, but I think I have it worked out now. ### 2025/July/07 * Continued working on lookahead design doc. * Expanded the lookahead sections. ### 2025/July/05 * Continued working on lookahead design doc. * Added screenshot of word suggestion list (in my local branch). * Replaced *XXXX* with *ZERO*, in the example. ### 2025/July/04 * Continued working on lookahead design doc. * Came up with new terminology. These terms avoid the conflict with the term *word list*, they are more understandable than *word fill*, and their relation to each other is obvious. Also I think *word suggestion* is nicer than *suggested word*, because it's a pure noun. * *Word suggestion list* * *Word suggestion algorithm* **Check-in:** > Great work on the bugs. A lot fixed, and the editor is significantly better! > * [ ] Jonathan to set up the glossary > > Proposal for next steps: > * [ ] Investigate existing open source solutions — survey of algorithms. > * [ ] Finish proposal > * [ ] Propose an algorithm to use > * [ ] Propose an API to target ### 2025/July/03 * Started work on [word fill lookahead design doc](https://pad.gnome.org/s/OAL239g-o). ### 2025/July/02 * Submitted issue for [editor cursor movement](https://gitlab.gnome.org/jrb/crosswords/-/issues/281). * Created [font testing](https://pad.gnome.org/s/6mTne5Ehs) doc. * Submitted issue for [*Clues* tab sidebar](https://gitlab.gnome.org/jrb/crosswords/-/issues/282). ### 2025/July/01 * Added some screenshots to my [last blog post](https://victorma.ca/posts/gsoc-4/). * Investigated [UI clipping bug](https://gitlab.gnome.org/jrb/crosswords/-/issues/280). * Finished fill lookahead notes doc. ### 2025/June/30 * Wrote [blog post 4](https://victorma.ca/posts/gsoc-4/). * Fleshed out [blog post 2](https://victorma.ca/posts/gsoc-2/) a bit. * Discovered another open source editor that I missed: [Crosshare](https://github.com/crosshare-org/crosshare). ### 2025/June/27 * [X] Was having trouble building libipuz. Then I realized I need an updated container image. * [X] Merged single suggested words list MR. * Created [branch](https://gitlab.gnome.org/jrb/crosswords/-/tree/fill-lookahead-sync) for synchronous word fill lookahead. * Started [notes document](https://pad.gnome.org/s/h5dBIlcr2) for the word fill lookahead, in preperation for writing the design doc. > **Jonathan update:** Great work! Do you want to touch on the issues. > We've reached a fork for next week: Victor has some newfound confidence in GTK and more importantly has proposed a number of improvements: > * [x] Fix the width and have it not bounce > * [x] Make the symmetry selector fit (possibly fixed by the above) > * [x] De-bounce the info panel: > * [x] Histogram for clue size and letter count > * [x] Cell count (see below) > * [x] Investigate monospace font. Do this by making sure we have the CSS set coorectly, and then we can play with it in the `style.css` file. > * [x] File a bug to have it go to the next cell in the editor. > > Something like this > ``` > Grid Composition: > \tNormal Cell: 55 (30%) > \tBlock: 30% (20%) > \tEmpty Cell: (10%) > ``` > > * [ ] Independent of above, Victor should iterate on the intersection doc. This will require writing down requirements and sketching out an implementation. Goal by end of week next week is to iterate through the implementation and come up with a rough design. > > Question from Victor: How do I run this in other languages? > ```bash > LANG=es_ES ./run src/crossword-editor > ``` > Question about autofill: > Link [here](https://jrb.pages.gitlab.gnome.org/crosswords/devel-docs/word-solver.html) One more thing. Think about another blog post at some point. ### 2025/June/26 * Reimplemented suggested words list MR with a single list and model. > **Jonathan update:** Set up libipuz for translations and [filed a bug](https://gitlab.gnome.org/Teams/Translation/Coordination/-/issues/337) to get it added to damned lies. ### 2025/June/25 * Finished work on removing second suggested words list. * [Opened MR](https://gitlab.gnome.org/jrb/crosswords/-/merge_requests/256). ### 2025/June/24 * Started looking into removing the second suggested words list. * Read through some GTK docs. * Looked at how `PlayClueList` works. * Reviewed notes from last call. * Merged rebus intersection fix. ### 2025/June/23 * Simplified rebus intersection fix. * Opened issue for rebus word suggestion behaviour. * Watched unicode video. Learned a lot from it! ### 2025/June/22 * Opened [rebus fix MR](https://gitlab.gnome.org/jrb/crosswords/-/merge_requests/251). ### 2025/June/21 * Looked into making the rebus fix testable. * Rebus offset logic is intertwined with the loop in `calculate_clue_word_pos()`. So it's not easy to extract it into a seperate, testable function. Would have to extract the entire loop. * Because of this, Jonathan said to skip tests. ### 2025/June/20 * Went through GUADEC slides and watched presentation. * [Made notes](https://pad.gnome.org/s/z0kHYSRx9). * Victor is worried that fixing the direction requires more GTK then he has. Extend project past November, would extend GSoC on resume. Less of a gap. Need to do it before midterm. **Jonathan's comments** * [x] _Optional:_ I found [this video](https://www.youtube.com/watch?v=ut74oHojxqo) (10 min). It’s pretty good * [x] Make MR for rebus intersection warning * [x] Time box to 2 days max the fix to the EditPlayList. Plan of attack: * Remove one of the lists/windows from the `edit-word-list.ui` file, and update the C code appropriately. * Add the preferences group as a member of EditWordList and set its id. * Use `ipuz_clue_direction_to_string()` to get a user-visible string for display * [x] Start thinking about going deeper in the search. * [x] Start a branch to do this in. * [ ] Write an initial design doc * [ ] To make it easier, start with it being synchronous and debug it that way. Once it works, we'll look into adding a thread * [ ] Jonathan: Look into extending date. ### 2025/June/19 * Started looking into how to remove the second suggested word list. ### 2025/June/18 * Got a working fix for rebus bug. * Opened MR for adding rebus hotkey to the editor's help overlay. ### 2025/June/17 * Got intersection MR ready for review. * Started looking into rebus bug. Here is the current plan: * If the assertion fails, run a function that calculates the proper `pos1` and `pos2`, by accounting for rebuses: * Check all the cells to the left of `pos1`. * Use `ipuz_guesses_get_guess` to determine the lengths of the guesses in each cell. * For every guess with a length greater than 1, add `length - 1` to a running total of the error amount, `error`. * The proper offset, after accounting for rebuses, is `pos1 + error`. * Repeat the same steps for the cells above `pos2`. This handles the vertical slot of the intersection. * Return the proper offsets for both `pos1` and `pos2`. * If the offsets returned by the function aren't different, then this means that the original assertion failure is a true failure---not simply a matter of not accounting for rebuses. * So, repeat the original assertion after the function. This catches any true assertion failures. > **JRB Update:** I think this is wrong — and way too complicated. I think you can fix this by accounting for the rebus clues correctly in `calculate_clue_word_pos()`. ### 2025/June/16 * Published [blog post 3](https://victorma.ca/posts/strange-bug/). * Cleaned up intersection MR. * Uncommented the rest of my tests and they all pass. ### 2025/June/13 * Started looking into [rebus bug](https://gitlab.gnome.org/jrb/crosswords/-/issues/268). * [Rebus bug notes](https://pad.gnome.org/s/QZBPeNvMH). * Where is the code for rebus-handling, in general? #### Meeting notes * Victor is really on the right path * Next steps: * [x] Victor to remove draft from his MR; looks good overall _and ping jrb when it's ready for review_ * [x] Victor to look into the rebus editor problem. It will involve an API change. Suggest: Once he has an API he's comfortable with, create a draft of that API and _ping jrb to take a look._ * [ ] Jonathan to look into why Test Word List isn't stable. Weird * [ ] If/When done, before Friday, start looking into the unstable text bug. aka removing across/down * [ ] Followups: Possibly optimize instersect * [ ] Followups: Possibly start looking into another level of looksup to detect better words async ### 2025/June/12 * Worked on tests for intersection bug. * Fixed a problem with my `word_array_equals` function, which was causing my tests to fail. * Found [a problem](https://pad.gnome.org/s/ggjo6YWov) with the test word list, which is causing my tests to fail. ### 2025/June/11 * Worked on tests for intersection bug. * Got order check working for `intersection_test`. * Currently debugging `equivalent_intersections_test`. ### 2025/June/10 * Worked on tests for intersection bug. * Added all the necessary code. Just need to debug it now. ### 2025/June/09 * Started fixing intersection bug. * Added a sort function that sorts `WordArray` by `WordIndex->index`. * This fix looks like it works. * Still need to handle edge cases. * Began work on tests. * Added order checking function. ### 2025/June/06 * Investigated bug and added notes to the doc. **Call Between Victor and Jonathan** Victor has understood the problem really well; it's coding time. Jonathan suggests three paths forward: * [x] Are we losing words? We aren't sorting right. Victor needs to add a manual word_list_sort() to the end of the intersection code. Once done, tests should pass * [x] Victor should look at removing the across/down and try to debounce the sidebar * [x] Decide which path forward: * [x] Async: One step of look ahead for the word-suggestions. Hard to calc, puts off overlay for a bit ← **preferred** * [ ] Sync: Look into doing unch detection. Easy to calc; need to figure out overlay ### 2025/June/05 * Finished looking at intersection function. * Did some more testing of the bug. I've figured out roughly [what's going on](https://gitlab.gnome.org/jrb/crosswords/-/issues/269#note_2462081). ### 2025/June/04 * Continued looking at intersection function. * Added more notes to the notes doc. * Added diagrams to the notes doc. I think making these was helpful for solidifying my understanding, and will serve as a useful reference, going forward. * Resource word list section. * Resource filter fragments section. ### 2025/June/03 * Read through docs for `word-list.c`. * Started looking at intersection function. * Created [notes doc](https://pad.gnome.org/s/R5IvXtNwS). ### 2025/June/02 * Opened issue for [word suggestions bug](https://gitlab.gnome.org/jrb/crosswords/-/issues/269). * Published [blog post 2](https://victorma.ca/posts/coding-begins). ### 2025/May/30 * Finished feature ideas doc. * Created doc about the [fill look-ahead problem](https://pad.gnome.org/s/Tl93B05Yp) I talked about last meeting. * I didn't explain it properly last time, but the problem I noticed does exist in `master`. * Next steps: * [x] Victor to file and figure out intersection bug * [x] Victor to look into which of the things he wants to focus on * [x] Jonathan to look into overlay with Federico * Victor's thoughts: * I had the unch detection feature in mind as a good first task. However, it would immediately run into needing overlay machinery. * Hopefully I can figure out the intersection bug, because that code would not involve any overlay stuff. So it would be good to do while the overlay stuff is being figured out. * Also, fixing the overlay bug should give me greater insight into if I should work on a fill-related task afterward. * Additional thoughts from Jonathan: * Agree with the above. * I didn't get there, but a couple hints for debugging the intersection bug: * The code to determine that list is `word_list_find_intersection()` in `src/word-list.c`. There's documentation about it in `doc/word-list.md` and the code. * It's called in `edit_word_list_recalculate()` from `edit_word_list_update()`. Maybe make sure you're calling it with the right arguments as a quick check * Whatever you do, we should get a good test case when this is done. ### 2025/May/29 * Continued work on feature ideas doc. * Some observations: * I was wrong about most editors using a per-slot heatmap. In fact, most use a per-cell heatmap. (A minority do use a per-slot heatmap.) * Jonathan mentioned Exet's heatmap being confusing when he first saw it. I agree, and I think even once you understand it's a heat map, it's still ugly and makes the grid cluttered. * Other editors use a light background color, which is much clearer visually, and also a bit more intuitive (though probably still could benefit from a quick tooltip). * Jump-to-most-constrained-slot is a very common feature and should be high priority to implement. * Using a single column for word suggestions is probably the right solution for the sidebar jumping problem. ### 2025/May/28 * Continued work on feature ideas doc. ### 2025/May/27 * Continued work on feature ideas doc. * Sent email to Crossfire author (CC'ed Jonathan). * Found another open source editor: [Qxw](https://www.quinapalus.com/qxw.html) ([GitHub repo](https://github.com/klochner/Qxw)). * This wasn't one of the editors I looked at. I found it mentioned in Exet's README, just now. ### 2025/May/26 * Started work on [feature ideas doc](https://pad.gnome.org/s/dxgb8XiY4). * Checked if any editors other than Exet are open source. * [Ingrid](https://pad.gnome.org/s/aGYPwTen5#Ingrid), which I think is quite a good editor, has an [open source core](https://github.com/rf-/ingrid_core). * Their [fill algorithm code](https://github.com/rf-/ingrid_core/blob/c082b9ec448516b8ee031424552d9eb6993f38e4/src/backtracking_search.rs#L1-L5) looks like it's well documented. ### 2025/May/23 * Finished prior art investigation. * Finished Crosserville section. * Finished Crossword Compiler section. **Checkin** * Fabulous work overall * Next steps: * [x] Victor to distill the results into a few possible ones, prioritised * [x] Summary of the existing features, roughly prioritised by seeming usefuleness and common * [x] (And turn it into a blog post maybe?) * [x] Target of next Friday, decide on a few that are high value to attempt for the summer * [ ] Bonus: Probably do the summary of printing for Toluwalake * [x] Bonus: Mail crossfire author about wordlists * Jonathan will turn the features into issues so we can track them for later. ### 2025/May/22 * Continued prior art investigation. * Reworked and added notes to the CrossFire section. ### 2025/May/20 * Continued prior art investigation. * Added CrossFire notes. * Added Crosserville notes. * Made small edits to the doc. ### 2025/May/19 * Continued prior art investigation. * Added short reviews for each software. _**JRB:** This is looking fantastic! Fabulous work._ ### 2025/May/18 * Began prior art investigation. * Created doc for findings: https://pad.gnome.org/s/aGYPwTen5 ### 2025/May/17 * Compiled list of crossword construction software to investigate for construction aids. ### 2025/May/10-16 * Created blog: https://victorma.ca/ * Published first blog post: https://victorma.ca/posts/gsoc-introduction/ * Added blog to Planet GNOME. * Obtained GNOME developer access. ### 2025/May/10 * First call with Victor.