unification-fd: Simple generic unification algorithms.

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

Warnings:

Simple generic unification algorithms.


[Skip to Readme]

Properties

Versions 0.5.0, 0.6.0, 0.7.0, 0.8.0, 0.8.1, 0.9.0, 0.10.0, 0.10.0.1, 0.11.0, 0.11.0, 0.11.1, 0.11.2, 0.11.2.2, 0.12.0
Change log CHANGELOG
Dependencies base (>=2.0 && <5), containers, logict (>=0.4 && <0.7.1), mtl (>=2.0) [details]
License BSD-3-Clause
Copyright Copyright (c) 2007--2021 wren gayle romano
Author wren gayle romano
Maintainer winterkoninkje@gmail.com
Category Algebra, Algorithms, Compilers/Interpreters, Language, Logic, Unification
Home page https://wrengr.org/software/hackage.html
Source repo head: git clone https://github.com/wrengr/unification-fd
Uploaded by WrenRomano at 2021-02-23T23:52:20Z

Modules

[Index] [Quick Jump]

Flags

Automatic Flags
NameDescriptionDefault
base4

base-4.0 emits "Prelude deprecated" messages in order to get people to be explicit about which version of base they use.

Enabled
splitbase

base-3.0 (GHC 6.8) broke out the packages: array, bytestring, containers, directory, old-locale, old-time, packedstring, pretty, process, random.

Enabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for unification-fd-0.11.0

[back to package description]

unification-fd

Hackage version Hackage-Deps TravisCI Build Status CircleCI Build Status

The unification-fd package offers generic functions for single-sorted first-order structural unification (think of programming in Prolog, or of the metavariables in type inference)12. The library is sufficient for implementing higher-rank type systems à la Peyton Jones, Vytiniotis, Weirich, Shields, but bear in mind that unification variables are the metavariables of type inference— not the type-variables.

Install

This is a simple package and should be easy to install. You should be able to use one of the following standard methods to install it.

-- With cabal-install and without the source:
$> cabal install unification-fd

-- With cabal-install and with the source already:
$> cd unification-fd
$> cabal install

-- Without cabal-install, but with the source already:
$> cd unification-fd
$> runhaskell Setup.hs configure --user
$> runhaskell Setup.hs build
$> runhaskell Setup.hs test
$> runhaskell Setup.hs haddock --hyperlink-source
$> runhaskell Setup.hs copy
$> runhaskell Setup.hs register

The test step is optional and currently does nothing. The Haddock step is also optional. If you see some stray lines that look like this:

mkUsageInfo: internal name? t{tv a7XM}

Feel free to ignore them. They shouldn't cause any problems, even though they're unsightly. This should be fixed in newer versions of GHC. For more details, see:

http://hackage.haskell.org/trac/ghc/ticket/3955

If you get a bunch of type errors about there being no MonadLogic instance for StateT, this means that your copy of the logict library is not compiled against the same mtl that we're using. To fix this, update logict to use the same mtl.

Portability

An effort has been made to make the package as portable as possible. However, because it uses the ST monad and the mtl-2 package it can't be H98 nor H2010. However, it only uses the following common extensions which should be well supported3:

Description

The unification API is generic in the type of the structures being unified and in the implementation of unification variables, following the two-level types pearl of Sheard (2001). This style mixes well with Swierstra (2008), though an implementation of the latter is not included in this package.

That is, all you have to do is define the functor whose fixed-point is the recursive type you're interested in:

-- The non-recursive structure of terms
data S a = ...

-- The recursive term type
type PureTerm = Fix S

And then provide an instance for Unifiable, where zipMatch performs one level of equality testing for terms and returns the one-level spine filled with pairs of subterms to be recursively checked (or Nothing if this level doesn't match).

class (Traversable t) => Unifiable t where
    zipMatch :: t a -> t b -> Maybe (t (a,b))

The choice of which variable implementation to use is defined by similarly simple classes Variable and BindingMonad. We store the variable bindings in a monad, for obvious reasons. In case it's not obvious, see Dijkstra et al. (2008) for benchmarks demonstrating the cost of naively applying bindings eagerly.

There are currently two implementations of variables provided: one based on STRefs, and another based on a state monad carrying an IntMap. The former has the benefit of O(1) access time, but the latter is plenty fast and has the benefit of supporting backtracking. Backtracking itself is provided by the logict package and is described in Kiselyov et al. (2005).

In addition to this modularity, unification-fd implements a number of optimizations over the algorithm presented in Sheard (2001)— which is also the algorithm presented in Cardelli (1987).

These optimizations pass a test suite for detecting obvious errors. If you find any bugs, do be sure to let me know. Also, if you happen to have a test suite or benchmark suite for unification on hand, I'd love to get a copy.

Notes and limitations

References

Luca Cardelli (1987)
Basic polymorphic typechecking. Science of Computer Programming, 8(2): 147–172.
Atze Dijkstra, Arie Middelkoop, S. Doaitse Swierstra (2008)
Efficient Functional Unification and Substitution. Technical Report UU-CS-2008-027, Utrecht University.
Simon Peyton Jones, Dimitrios Vytiniotis, Stephanie Weirich, Mark Shields (2007)
Practical type inference for arbitrary-rank types. JFP 17(1). The online version has some minor corrections/clarifications.
Oleg Kiselyov, Chung-chieh Shan, Daniel P. Friedman, and Amr Sabry (2005)
Backtracking, Interleaving, and Terminating Monad Transformers. ICFP.
Tim Sheard (2001)
Generic Unification via Two-Level Types and Parameterized Modules, Functional Pearl. ICFP.
Tim Sheard and Emir Pasalic (2004)
Two-Level Types and Parameterized Modules. JFP 14(5): 547–587. This is an expanded version of Sheard (2001) with new examples.
Wouter Swierstra (2008)
Data types à la carte, Functional Pearl. JFP 18: 423–436.
1

At present the library does not appear amenable for implementing higher-rank unification itself; i.e., for higher-ranked metavariables, or higher-ranked logic programming. To be fully general we'd have to abstract over which structural positions are co/contravariant, whether the unification variables should be predicative or impredicative, as well as the isomorphisms of moving quantifiers around. It's on my todo list, but it's certainly non-trivial. If you have any suggestions, feel free to contact me.

2

At present it is only suitable for single-sorted (aka untyped) unification, à la Prolog. In the future I aim to support multi-sorted (aka typed) unification, however doing so is complicated by the fact that it can lead to the loss of MGUs; so it will likely be offered as an alternative to the single-sorted variant, similar to how the weighted path-compression is currently offered as an alternative.

3

With the exception of fundeps which are notoriously difficult to implement. However, they are supported by Hugs and GHC 6.6, so I don't feel bad about requiring them. Once the API stabilizes a bit more I plan to release a unification-tf package which uses type families instead, for those who feel type families are easier to implement or use. There have been a couple requests for unification-tf, so I've bumped it up on my todo list.