diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..df89c18 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "ext/sphinx-extensions"] + path = ext/sphinx-extensions + url = https://github.com/dylan-lang/sphinx-extensions diff --git a/documentation/Makefile b/documentation/Makefile new file mode 100644 index 0000000..d0c3cbf --- /dev/null +++ b/documentation/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/documentation/make.bat b/documentation/make.bat new file mode 100644 index 0000000..747ffb7 --- /dev/null +++ b/documentation/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/documentation/source/collection-utilities.rst b/documentation/source/collection-utilities.rst new file mode 100644 index 0000000..981f62a --- /dev/null +++ b/documentation/source/collection-utilities.rst @@ -0,0 +1,38 @@ +The collection-utilities Module +=============================== + +.. current-library:: collection-extensions +.. current-module:: collection-utilities + +Reference +--------- + +**TODO**: These docs are just an auto-generated skeleton so +far. https://github.com/dylan-lang/collection-extensions/issues/2 + +.. generic-function:: key-exists? + + :signature: key-exists? (collection key) => (key-exists? value) + + :parameter collection: An instance of :drm:``. + :parameter key: An instance of :drm:``. + :value key-exists?: An instance of :drm:``. + :value value: An instance of :drm:``. + +.. generic-function:: singleton? + :open: + + :signature: singleton? (collection) => (singleton?) + + :parameter collection: An instance of :drm:``. + :value singleton?: An instance of :drm:``. + +.. method:: singleton? + :specializer: + +.. method:: singleton? + :specializer: + +.. method:: singleton? + :specializer: + diff --git a/documentation/source/conf.py b/documentation/source/conf.py new file mode 100644 index 0000000..ee298e7 --- /dev/null +++ b/documentation/source/conf.py @@ -0,0 +1,73 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. + +import os +import sys +sys.path.insert(0, os.path.abspath('../../ext/sphinx-extensions/sphinxcontrib')) +import dylan.themes as dylan_themes + + +# -- Project information ----------------------------------------------------- + +project = 'Collection Extensions' +copyright = '1998, 1999, 2000 Gwydion Dylan Maintainers' + +# The full version, including alpha/beta/rc tags +release = 'v0.2.0' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'dylan.domain', + 'sphinx.ext.intersphinx' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['_build'] + +# This makes it so that each document doesn't have to use +# .. default-domain:: dylan +# but they probably should anyway, so that they can be built separately +# without depending on this top-level config file. +primary_domain = 'dylan' + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = dylan_themes.get_html_theme_default() + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +html_theme_options = dylan_themes.get_html_theme_options_default() + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = [dylan_themes.get_html_theme_path()] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +html_title = "Collection Extensions" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/documentation/source/heap.rst b/documentation/source/heap.rst new file mode 100644 index 0000000..6bfadfe --- /dev/null +++ b/documentation/source/heap.rst @@ -0,0 +1,135 @@ +The heap Module +=============== + +.. current-library:: collection-extensions +.. current-module:: vector-search + +Overview +-------- + +A heap is an implementation of the abstract data type "sorted list". A heap +is a sorted sequence of items. Most likely the user will end up writing +something like + +.. code-block:: dylan + + define class () + slot priority; + slot data; + end; + +with appropriate methods defined for :drm:`<` and :drm:`=`. The user could, +however, have simply a sorted list of integers, or have some item where the +priority is an integral part of the item itself. + +:drm:`make` on heaps supports the ``less-than:`` keyword, which supply the +heap's comparison and defaults to :drm:`<`. + +Heaps support all the usual sequence operations. The most useful ones:: + + heap-push(heap, item) => updated-heap + heap-pop(heap) => smallest-element + first(heap) => smallest-element + second(heap) => second-smallest-element + add!(heap, item) => updated-heap + sort, sort! => sorted-sequence + +These are all "efficient" operations (defined below). As with :drm:`push` on +:drm:``, :func:`heap-push` is another name for :drm:`add!`, and does +exactly the same thing except that heap-push doesn't accept any keywords. +:drm:`sort` and :drm:`sort!` return a sequence that's not a heap. Not +necessarily efficient but useful anyhow:: + + add-new!(heap, item, #key test:, efficient:) => updated-heap + remove!(heap, item, #key test:, efficient:) => updated-heap + member?(item, heap, #key test:, efficient:) => + +The ``efficient:`` keyword defaults to ``#f``. If ``#t``, it uses the +:func:`random-iteration-protocol` (which is considerably more efficient, but +isn't really standard behavior, so it had to be optional). Conceivably most +sequence methods could support such a keyword, but they don't yet. + +The user can use :drm:`element-setter` or the iteration protocol to change an +item in the heap, but changing the priority of an item is an error and Bad +Things(tm) will happen. No error will be signaled. Both of these operations +are very inefficient. + +Heaps are **not** instances of :drm:``, although +:drm:`add!` and :func:`heap-pop` can magically change the size of the heap. + +Efficiency: Approximate running times of different operations are given +below: (N is the size of the heap) :: + + first, first-setter O(1) + second (but not second-setter) O(1) + size O(1) + add! O(lg N) + heap-push O(lg N) + heap-pop(heap) O(lg N) + sort, sort! O(N * lg N) + forward-iteration-protocol + setup: O(N) + next-state: O(lg N) + current-element: O(1) + current-element-setter: O(N) + backward-iteration-protocol + setup: O(N * lg N) + next-state: O(1) + current-element: O(1) + current-element-setter: O(N) + random-iteration-protocol + setup: O(1) + next-state: O(1) + current-element: O(1) + current-element-setter: O(1) + element(heap, M) O(M*lg N + N) + element-setter(value, heap, M) O(N + M*lg N + M) + +:drm:`element`, :drm:`element-setter` on arbitrary keys use the +:drm:`forward-iteration-protocol` (via the inherited methods), and have +accordingly bad performance. + +Reference +--------- + +The HEAP module +*************** + +.. current-module:: heap + + +.. class:: + + :superclasses: :drm:`` + + :keyword less-than: An instance of :drm:``. + :keyword size: An instance of :drm:``. + +.. generic-function:: heap-pop + + :signature: heap-pop (h) => (smallest-item) + + :parameter h: An instance of :class:``. + :value smallest-item: An instance of :drm:``. + +.. generic-function:: heap-push + + :signature: heap-push (h new-elt) => (changed-heap) + + :parameter h: An instance of :class:``. + :parameter new-elt: An instance of :drm:``. + :value changed-heap: An instance of :class:``. + +.. generic-function:: random-iteration-protocol + + :signature: random-iteration-protocol (collection) => (initial-state limit next-state finished-state? current-key current-element current-element-setter copy-state) + + :parameter collection: An instance of :class:``. + :value initial-state: An instance of :drm:``. + :value limit: An instance of :drm:``. + :value next-state: An instance of :drm:``. + :value finished-state?: An instance of :drm:``. + :value current-key: An instance of :drm:``. + :value current-element: An instance of :drm:``. + :value current-element-setter: An instance of :drm:``. + :value copy-state: An instance of :drm:``. diff --git a/documentation/source/index.rst b/documentation/source/index.rst new file mode 100644 index 0000000..1d6d33e --- /dev/null +++ b/documentation/source/index.rst @@ -0,0 +1,24 @@ +********************************* +The collection-extensions Library +********************************* + +.. current-library:: collection-extensions + +.. toctree:: + :maxdepth: 1 + :caption: Contents: + + collection-utilities + heap + sde-vector + self-organizing-list + sequence-diff + sequence-utilities + subseq + vector-search + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/documentation/source/sde-vector.rst b/documentation/source/sde-vector.rst new file mode 100644 index 0000000..7fbb842 --- /dev/null +++ b/documentation/source/sde-vector.rst @@ -0,0 +1,26 @@ +The sde-vector Module +===================== + +.. current-library:: collection-extensions +.. current-module:: sde-vector + +Overview +-------- + +Stretchy double ended vector -- A collection that has keys from -n to n, where +n is a non-negative integer. It's not technically a vector because the keys +don't start at 0, and so doesn't inherit a lot of sequence methods, but +otherwise it behaves like a vector. + + +Reference +--------- + +**TODO**: https://github.com/dylan-lang/collection-extensions/issues/2 + +.. class:: + + :superclasses: :drm:``, :drm:`` + + :keyword fill: An instance of :drm:``. + :keyword size: An instance of :drm:``. diff --git a/documentation/source/self-organizing-list.rst b/documentation/source/self-organizing-list.rst new file mode 100644 index 0000000..77ae260 --- /dev/null +++ b/documentation/source/self-organizing-list.rst @@ -0,0 +1,12 @@ +The self-organizing-list Module +=============================== + +.. current-library:: collection-extensions +.. current-module:: self-organizing-list + + +.. class:: + + :superclasses: :drm:``, :drm:`` + + :keyword test: An instance of :drm:``. diff --git a/documentation/source/sequence-diff.rst b/documentation/source/sequence-diff.rst new file mode 100644 index 0000000..fe1e884 --- /dev/null +++ b/documentation/source/sequence-diff.rst @@ -0,0 +1,73 @@ +The sequence-diff Module +======================== + +.. current-library:: collection-extensions +.. current-module:: sequence-diff + + +Overview +-------- + +The sequence-diff module implements an algorithm that accomplishes something +similar to the Unix diff utility. (Your actual diff utility may or may not use +this algorithm, but it does something similar.) + +Algorithm is by Webb Miller and Eugene W. Myers, published as "A File +Comparison Program", p. 1025-1040 of Software--Practice and Experience, +November 1985. Quite frankly the algorithm is rather incomprehensible in +source code form, so you might want to think about getting the paper. + + +Reference +--------- + +**TODO**: These docs are just an auto-generated skeleton so +far. https://github.com/dylan-lang/collection-extensions/issues/2 + +.. class:: + + :superclasses: :class:`` + + +.. class:: + + :superclasses: :class:`` + + :keyword required source-index: An instance of :drm:``. + +.. class:: + :abstract: + + :superclasses: :drm:`` + + :keyword count: An instance of :drm:``. + :keyword required dest-index: An instance of :drm:``. + +.. generic-function:: dest-index + + :signature: dest-index (object) => (value) + + :parameter object: An instance of :class:``. + :value value: An instance of :drm:``. + +.. generic-function:: element-count + + :signature: element-count (object) => (value) + + :parameter object: An instance of :class:``. + :value value: An instance of :drm:``. + +.. generic-function:: sequence-diff + + :signature: sequence-diff (s1 s2) => (script) + + :parameter s1: An instance of :drm:``. + :parameter s2: An instance of :drm:``. + :value script: An instance of :const:`