[{"name":"Book.Ch1","comment":" Relations from Chapter 1 of The Reasoned Schemer (2nd Edition).\n\n@docs teacupo, tea, cup\n\n","unions":[],"aliases":[],"values":[{"name":"cup","comment":" ","type":"Logic.Value a"},{"name":"tea","comment":" ","type":"Logic.Value a"},{"name":"teacupo","comment":" ","type":"Logic.Value a -> Logic.Goal a"}],"binops":[]},{"name":"Book.Ch2","comment":" Relations from Chapter 2 of The Reasoned Schemer (2nd Edition).\n\n@docs caro, cdro\n@docs conso, consoUsingEquals\n@docs nullo, pairo, singletono\n@docs caroUsingConso, cdroUsingConso\n\n","unions":[],"aliases":[],"values":[{"name":"caro","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"caroUsingConso","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"cdro","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"cdroUsingConso","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"conso","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"consoUsingEquals","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"nullo","comment":" ","type":"Logic.Value a -> Logic.Goal a"},{"name":"pairo","comment":" ","type":"Logic.Value a -> Logic.Goal a"},{"name":"singletono","comment":" ","type":"Logic.Value a -> Logic.Goal a"}],"binops":[]},{"name":"Book.Ch3","comment":" Relations from Chapter 3 of The Reasoned Schemer (2nd Edition).\n\n@docs listo, lolo, loso, membero, properMembero\n\n","unions":[],"aliases":[],"values":[{"name":"listo","comment":" ","type":"Logic.Value a -> Logic.Goal a"},{"name":"lolo","comment":" ","type":"Logic.Value a -> Logic.Goal a"},{"name":"loso","comment":" ","type":"Logic.Value a -> Logic.Goal a"},{"name":"membero","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"properMembero","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"}],"binops":[]},{"name":"Book.Ch4","comment":" Relations from Chapter 4 of The Reasoned Schemer (2nd Edition).\n\n@docs appendo, swappendo, unwrapo\n\n","unions":[],"aliases":[],"values":[{"name":"appendo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"swappendo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"unwrapo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"}],"binops":[]},{"name":"Book.Ch5","comment":" Relations from Chapter 5 of The Reasoned Schemer (2nd Edition).\n\n@docs memo, rembero\n\n","unions":[],"aliases":[],"values":[{"name":"memo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"rembero","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"}],"binops":[]},{"name":"Book.Ch6","comment":" Relations from Chapter 6 of The Reasoned Schemer (2nd Edition).\n\n@docs alwayso, nevero, veryRecursiveo\n\n","unions":[],"aliases":[],"values":[{"name":"alwayso","comment":" ","type":"Logic.Goal a"},{"name":"nevero","comment":" ","type":"Logic.Goal a"},{"name":"veryRecursiveo","comment":" ","type":"Logic.Goal a"}],"binops":[]},{"name":"Book.Ch7","comment":" Relations from Chapter 7 of The Reasoned Schemer (2nd Edition).\n\n@docs zero, one\n@docs bitXoro, bitAndo, halfAddero, fullAddero\n@docs buildNum, numZero, numOne\n@docs poso, greaterThan1o\n@docs addero, genAddero, pluso, minuso\n@docs lengtho\n\n","unions":[],"aliases":[],"values":[{"name":"addero","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"bitAndo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"bitXoro","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"buildNum","comment":" ","type":"Basics.Int -> Logic.Value a"},{"name":"fullAddero","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"genAddero","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"greaterThan1o","comment":" ","type":"Logic.Value a -> Logic.Goal a"},{"name":"halfAddero","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"lengtho","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"minuso","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"numOne","comment":" ","type":"Logic.Value a"},{"name":"numZero","comment":" ","type":"Logic.Value a"},{"name":"one","comment":" ","type":"Logic.Value a"},{"name":"pluso","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"poso","comment":" ","type":"Logic.Value a -> Logic.Goal a"},{"name":"zero","comment":" ","type":"Logic.Value a"}],"binops":[]},{"name":"Book.Ch7Alt","comment":" Relations from Chapter 7 of The Reasoned Schemer (2nd Edition).\n\nIt illustrates how you can use `bitNando` as the starting primitive relation.\n\n@docs zero, one\n@docs bitNando\n@docs bitXoro, bitAndo\n\n","unions":[],"aliases":[],"values":[{"name":"bitAndo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"bitNando","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"bitXoro","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"one","comment":" ","type":"Logic.Value a"},{"name":"zero","comment":" ","type":"Logic.Value a"}],"binops":[]},{"name":"Book.Ch8","comment":" Relations from Chapter 8 of The Reasoned Schemer (2nd Edition).\n\n@docs timeso\n@docs equalLo, lessThanLo, lessThanOrEqualLo\n@docs lessThano, lessThanOrEqualo\n@docs originalDivo\n@docs splito, divo\n@docs logo, repeatedMulo\n@docs expo\n\n","unions":[],"aliases":[],"values":[{"name":"divo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"equalLo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"expo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"lessThanLo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"lessThanOrEqualLo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"lessThanOrEqualo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"lessThano","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"logo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"originalDivo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"repeatedMulo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"splito","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"timeso","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"}],"binops":[]},{"name":"Book.Ch9","comment":" Relations from Chapter 9 of The Reasoned Schemer (2nd Edition).\n\n@docs notPastao, pasta\n@docs onceo\n@docs bumpo, genAndTestPluso, enumeratePluso, enumerateo\n\n","unions":[],"aliases":[],"values":[{"name":"bumpo","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"enumeratePluso","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"enumerateo","comment":" ","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"genAndTestPluso","comment":" ","type":"Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"notPastao","comment":" ","type":"Logic.Value a -> Logic.Goal a"},{"name":"onceo","comment":" ","type":"Logic.Goal a -> Logic.Goal a"},{"name":"pasta","comment":" ","type":"Logic.Value a"}],"binops":[]},{"name":"Logic","comment":" A high-level API that brings together the `Logic.*` submodules into a cohesive module.\n\n\n# Value\n\n@docs Value, Constant\n@docs int, float, bool, char, string, custom, toConstant\n@docs null, cons, list, dottedList, car, cdr, uncons\n\n\n# Goal\n\n@docs Goal\n@docs succeed, fail\n@docs always, never\n\n\n# Relational operators\n\n@docs equals, disj2, disj, conj2, conj, conde\n\n\n# Define\n\n@docs lazy\n\n\n# Lexically-scoped logic variables\n\n@docs fresh, fresh2, fresh3, fresh4, fresh5, fresh6, fresh7, fresh8\n\n\n# Non-relational operators\n\nSee `Logic.Goal` for more details on these operators.\n\n@docs once, conda, condu\n\n\n# Run\n\nSee `Logic.Goal` for more details on these runners.\n\n@docs run, run2, run3, run4, run5, run6, run7, run8\n@docs runAtMost, run2AtMost, run3AtMost, run4AtMost, run5AtMost, run6AtMost, run7AtMost, run8AtMost\n\n\n# Debug\n\n@docs toString\n@docs Presenter, customToString\n\n","unions":[{"name":"Constant","comment":" Work with integers, floats, booleans, characters, and strings out of the box. There's\nalso the possibility to bring in your own custom types.\n","args":["a"],"cases":[["Int",["Basics.Int"]],["Float",["Basics.Float"]],["Bool",["Basics.Bool"]],["Char",["Char.Char"]],["String",["String.String"]],["Custom",["a"]]]},{"name":"Presenter","comment":" Used by [`customToString`](#customToString) to determine how to represent your custom type.\n\nWith the `Default` constructor you get to use the default representation for the constants while\nproviding a function to represent your custom type.\n\nThe default representation for the constants is as follows:\n\n    toString [ int 1 ] == \"(1)\"\n\n    toString [ float 3.14 ] == \"(3.14)\"\n\n    toString [ bool True ] == \"(#t)\"\n\n    toString [ bool False ] == \"(#f)\"\n\n    toString [ char 'a' ] == \"(a)\"\n\n    toString [ string \"xyz\" ] == \"(xyz)\"\n\nIf you want to change the default representation for the constants you can do that by using\nthe `Alternative` constructor.\n\n","args":["a"],"cases":[["Default",["a -> String.String"]],["Alternative",["Logic.Constant a -> String.String"]]]}],"aliases":[{"name":"Goal","comment":" Imbue the underlying `Goal` type with a richer set of constants.\n\nSee `Logic.Goal` for more details.\n\n","args":["a"],"type":"Logic.Goal.Goal (Logic.Constant a)"},{"name":"Value","comment":" A rich default set of values that can be associated with (logic) variables.\n","args":["a"],"type":"Logic.Value.Value (Logic.Constant a)"}],"values":[{"name":"always","comment":" A goal that succeeds an unbounded number of times.\n","type":"Logic.Goal a"},{"name":"bool","comment":" Create a boolean value.\n","type":"Basics.Bool -> Logic.Value a"},{"name":"car","comment":" Get the first value from a dotted pair, if possible.\n\n    car (cons x y) == Just x\n\n    car null == Nothing\n\n    car (string \"(cons x y)\") == Nothing\n\n","type":"Logic.Value a -> Maybe.Maybe (Logic.Value a)"},{"name":"cdr","comment":" Get the second value from a dotted pair, if possible.\n\n    cdr (cons x y) == Just y\n\n    cdr null == Nothing\n\n    cdr (string \"(cons x y)\") == Nothing\n\n","type":"Logic.Value a -> Maybe.Maybe (Logic.Value a)"},{"name":"char","comment":" Create a character value.\n","type":"Char.Char -> Logic.Value a"},{"name":"conda","comment":" ","type":"List.List (List.List (Logic.Goal a)) -> Logic.Goal a"},{"name":"conde","comment":" The disjunction of conjunctions.\n\nSee `Logic.Goal.conde` for more details.\n\n","type":"List.List (List.List (Logic.Goal a)) -> Logic.Goal a"},{"name":"condu","comment":" ","type":"List.List (List.List (Logic.Goal a)) -> Logic.Goal a"},{"name":"conj","comment":" The conjunction of zero or more goals. It succeeds if and only if all the goals succeed.\n","type":"List.List (Logic.Goal a) -> Logic.Goal a"},{"name":"conj2","comment":" The **conjunction** of two goals. It succeeds if and only if both goals succeed.\n","type":"Logic.Goal a -> Logic.Goal a -> Logic.Goal a"},{"name":"cons","comment":" Create a dotted pair of any two values.\n","type":"Logic.Value a -> Logic.Value a -> Logic.Value a"},{"name":"custom","comment":" Create a value out of your custom type.\n","type":"a -> Logic.Value a"},{"name":"customToString","comment":" Convert to a representation that's useful for debugging and testing.\n\nAdditionally, you get to determine how to represent your custom type.\n\n","type":"Logic.Presenter a -> List.List (Logic.Value a) -> String.String"},{"name":"disj","comment":" The disjunction of zero or more goals. It succeeds if and only if there is at least one goal that succeeds.\n","type":"List.List (Logic.Goal a) -> Logic.Goal a"},{"name":"disj2","comment":" The **disjunction** of two goals. It succeeds if and only if either of the goals succeed.\n","type":"Logic.Goal a -> Logic.Goal a -> Logic.Goal a"},{"name":"dottedList","comment":" Create an improper list of two or more values.\n\n    dottedList (int 1) [] (bool True) == cons (int 1) (bool True)\n\n    dottedList (int 1) [ bool True ] (char 'a') == cons (int 1) (cons (bool True) (char 'a'))\n\n","type":"Logic.Value a -> List.List (Logic.Value a) -> Logic.Value a -> Logic.Value a"},{"name":"equals","comment":" Try to unify two values. It succeeds if unification is possible, and fails otherwise.\n","type":"Logic.Value a -> Logic.Value a -> Logic.Goal a"},{"name":"fail","comment":" A goal that fails.\n","type":"Logic.Goal a"},{"name":"float","comment":" Create a floating-point value.\n","type":"Basics.Float -> Logic.Value a"},{"name":"fresh","comment":" Create a lexically-scoped logic variable.\n\n    fresh\n        (\\fruit ->\n            equals (Const \"plum\") fruit\n        )\n\n","type":"(Logic.Value a -> Logic.Goal a) -> Logic.Goal a"},{"name":"fresh2","comment":" Create two lexicaly-scoped logic variables.\n","type":"(Logic.Value a -> Logic.Value a -> Logic.Goal a) -> Logic.Goal a"},{"name":"fresh3","comment":" Create three lexicaly-scoped logic variables.\n","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> Logic.Goal a"},{"name":"fresh4","comment":" Create four lexicaly-scoped logic variables.\n","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> Logic.Goal a"},{"name":"fresh5","comment":" Create five lexicaly-scoped logic variables.\n","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> Logic.Goal a"},{"name":"fresh6","comment":" Create six lexicaly-scoped logic variables.\n","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> Logic.Goal a"},{"name":"fresh7","comment":" Create seven lexicaly-scoped logic variables.\n","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> Logic.Goal a"},{"name":"fresh8","comment":" Create eight lexicaly-scoped logic variables.\n","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> Logic.Goal a"},{"name":"int","comment":" Create an integer value.\n","type":"Basics.Int -> Logic.Value a"},{"name":"lazy","comment":" Useful for defining recursive goals.\n","type":"(() -> Logic.Goal a) -> Logic.Goal a"},{"name":"list","comment":" Create a proper list of zero or more values.\n\n    list [] == null\n\n    list [ int 1 ] == cons (int 1) null\n\n    list [ int 1, bool True ] == cons (int 1) (cons (bool True) null)\n\n    list [ int 1, bool True, char 'a' ] == cons (int 1) (cons (bool True) (cons (char 'a') null))\n\n","type":"List.List (Logic.Value a) -> Logic.Value a"},{"name":"never","comment":" A goal that neither succeeds nor fails.\n","type":"Logic.Goal a"},{"name":"null","comment":" The empty list value.\n","type":"Logic.Value a"},{"name":"once","comment":" ","type":"Logic.Goal a -> Logic.Goal a"},{"name":"run","comment":" ","type":"(Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run2","comment":" ","type":"(Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run2AtMost","comment":" ","type":"Basics.Int -> (Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run3","comment":" ","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run3AtMost","comment":" ","type":"Basics.Int -> (Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run4","comment":" ","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run4AtMost","comment":" ","type":"Basics.Int -> (Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run5","comment":" ","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run5AtMost","comment":" ","type":"Basics.Int -> (Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run6","comment":" ","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run6AtMost","comment":" ","type":"Basics.Int -> (Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run7","comment":" ","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run7AtMost","comment":" ","type":"Basics.Int -> (Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run8","comment":" ","type":"(Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"run8AtMost","comment":" ","type":"Basics.Int -> (Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"runAtMost","comment":" ","type":"Basics.Int -> (Logic.Value a -> Logic.Goal a) -> List.List (Logic.Value a)"},{"name":"string","comment":" Create a string value.\n","type":"String.String -> Logic.Value a"},{"name":"succeed","comment":" A goal that succeeds.\n","type":"Logic.Goal a"},{"name":"toConstant","comment":" Convert a value to a constant, if possible.\n\n    toConstant (int 5) == Just (Int 5)\n\n    toConstant null == Nothing\n\n","type":"Logic.Value a -> Maybe.Maybe (Logic.Constant a)"},{"name":"toString","comment":" Convert to a representation that's useful for debugging and testing.\n\n    toString [ int 1, float 3.14, bool True, bool False, char 'c', string \"apple\", custom \"banana\" ] == \"(1 3.14 #t #f c apple banana)\"\n\n    toString [ null, cons (int 1) (int 2), list [ int 1 ], list [ int 1, bool True ] ] == \"(() (1 . 2) (1) (1 #t))\"\n\n    toString [ dottedList (int 1) [ bool True ] (char 'a') ] == \"((1 #t . a))\"\n\n**N.B.** _For convenience, it assumes your custom type is `String`. If your custom type\nis something else you can use [`customToString`](#customToString) instead._\n\n","type":"List.List (Logic.Value String.String) -> String.String"},{"name":"uncons","comment":" Get the first and second value from a dotted pair, if possible.\n\n    uncons (cons x y) == Just ( x, y )\n\n    uncons null == Nothing\n\n    uncons (string \"(cons x y)\") == Nothing\n\n","type":"Logic.Value a -> Maybe.Maybe ( Logic.Value a, Logic.Value a )"}],"binops":[]},{"name":"Logic.Goal","comment":" A low-level API for constructing, combining, and running goals.\n\n\n# Goal\n\nIn general, a **goal** is a function that takes a substitution and, if it returns,\nproduces a stream of substitutions. Under the hood, there's slightly more to it.\n\n@docs Goal\n@docs succeed, fail\n@docs always, never\n\n\n# Relational operators\n\n@docs equals, disj2, disj, conj2, conj, conde\n\n\n# Define\n\n@docs lazy\n\n\n# Lexically-scoped logic variables\n\n[`callFresh`](#callFresh) and the [`fresh`](#fresh) family of functions create lexically-scoped logic variables.\n\n@docs callFresh, fresh, fresh2, fresh3, fresh4, fresh5, fresh6, fresh7, fresh8\n\n\n# Non-relational operators\n\n**BEWARE:** These operators may not work correctly for every goal ordering of a program.\n\n[`ifte`](#ifte) and [`once`](#once) are used to implement [`conda`](#conda) and [`condu`](#condu).\n\n`conda` and `condu` are used to prune a program's search tree, and can be used\nin place of [Prolog's cut](https://en.wikipedia.org/wiki/Cut_%28logic_programming%29) (`!`).\n\n@docs ifte, once, conda, condu\n\n\n# Run\n\n@docs Length, runS, run, run2, run3, run4, run5, run6, run7, run8\n\n\n# Debug\n\n@docs toString\n\n","unions":[{"name":"Goal","comment":" It either **succeeds**, **fails**, or **has no value**.\n\nA goal that **succeeds** returns a stream of one or more substitutions.\n\nA goal that **fails** returns an empty stream.\n\nA goal that **has no value** never returns.\n\n","args":["a"],"cases":[]},{"name":"Length","comment":" Used by the various run functions to determine the number of substitutions\nto take from a stream of substitutions.\n\n`Unbounded` means to take the entire stream of substitutions, which may be finite or infinite.\n\n","args":[],"cases":[["AtMost",["Basics.Int"]],["Unbounded",[]]]}],"aliases":[],"values":[{"name":"always","comment":" A goal that succeeds an unbounded number of times.\n\nContrast that with [`succeed`](#succeed), which succeeds only once.\n\n","type":"Logic.Goal.Goal a"},{"name":"callFresh","comment":" Create a lexically-scoped logic variable, with a given name.\n\n    callFresh \"fruit\"\n        (\\fruit ->\n            equals (Const \"plum\") fruit\n        )\n\n**N.B.** _You only have access to the variable within the function you provide._\n\n","type":"String.String -> (Logic.Value.Value a -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"conda","comment":"\n\n    conda\n        [ [ g11, ..., g1N1 ]\n        , [ g21, ..., g2N2 ]\n        , ...\n        , [ gM1, ..., gMNM ]\n        ]\n\nis equivalent to\n\n    ifte\n        g11\n        (conj [ g12, ..., g1N1 ])\n        (conda\n            [ [ g21, ..., g2N2 ]\n            , ...\n            , [ gM1, ..., gMNM ]\n            ]\n        )\n\nwhere `M >= 1`, `N1 >= 1`, and `Ni >= 0` for all `2 <= i <= M`.\n\nFor the case when `M = 0` or when `M >= 1` and `N1 = 0`, `conda` fails.\n\n**N.B.** _`conda` corresponds to Prolog's [soft-cut](https://www.swi-prolog.org/pldoc/doc%5Ffor?object=%28%2A-%3E%29/2)._\n\n","type":"List.List (List.List (Logic.Goal.Goal a)) -> Logic.Goal.Goal a"},{"name":"conde","comment":" The disjunction of conjunctions.\n\n    conde\n        [ [ g11, ..., g1N1 ]\n        , [ g21, ..., g2N2 ]\n        , ...\n        , [ gM1, ..., gMNM ]\n        ]\n\nis equivalent to\n\n    disj\n        [ conj [ g11, ..., g1N1 ]\n        , conj [ g21, ..., g2N2 ]\n        , ...\n        , conj [ gM1, ..., gMNM ]\n        ]\n\nwhere `M >= 0` and `Ni >= 0` for all `1 <= i <= M`.\n\nIf `M = 0` then we have `conde []`.\n\nIf `Ni = 0` for some `i` then the `(i-1)`th element of the list given to `conde` is the empty list.\n\n","type":"List.List (List.List (Logic.Goal.Goal a)) -> Logic.Goal.Goal a"},{"name":"condu","comment":"\n\n    condu\n        [ [ g11, g12, ..., g1N1 ]\n        , [ g21, g22, ..., g2N2 ]\n        , ...\n        , [ gM1, gM2, ..., gMNM ]\n        ]\n\nis equivalent to\n\n    conda\n        [ [ once g11, g12, ..., g1N1 ]\n        , [ once g21, g22, ..., g2N2 ]\n        , ...\n        , [ once gM1, gM2, ..., gMNM ]\n        ]\n\nwhere `M >= 0` and `Ni >= 0` for all `1 <= i <= M`.\n\nIf a `condu` line is empty, the equivalent `conda` line is also empty.\n\n**N.B.** _`condu` corresponds to Mercury's [committed choice](https://www.mercurylang.org/information/doc-release/mercury%5Fref/Committed-choice-nondeterminism.html)._\n\n","type":"List.List (List.List (Logic.Goal.Goal a)) -> Logic.Goal.Goal a"},{"name":"conj","comment":" The conjunction of zero or more goals. It succeeds if and only if all the goals succeed.\n","type":"List.List (Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"conj2","comment":" The **conjunction** of two goals. It succeeds if and only if both goals succeed.\n","type":"Logic.Goal.Goal a -> Logic.Goal.Goal a -> Logic.Goal.Goal a"},{"name":"disj","comment":" The disjunction of zero or more goals. It succeeds if and only if there is at least one goal that succeeds.\n","type":"List.List (Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"disj2","comment":" The **disjunction** of two goals. It succeeds if and only if either of the goals succeed.\n","type":"Logic.Goal.Goal a -> Logic.Goal.Goal a -> Logic.Goal.Goal a"},{"name":"equals","comment":" Try to unify two values. It succeeds if unification is possible, and fails otherwise.\n","type":"Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a"},{"name":"fail","comment":" A goal that fails.\n","type":"Logic.Goal.Goal a"},{"name":"fresh","comment":" Create a lexically-scoped logic variable.\n\n    fresh\n        (\\fruit ->\n            equals (Const \"plum\") fruit\n        )\n\n**N.B.** _It uses [`callFresh`](#callFresh) under the hood but\nyou have no control over the name of the variable. The name is\nonly useful for debugging purposes anyway._\n\n","type":"(Logic.Value.Value a -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"fresh2","comment":" Create two lexicaly-scoped logic variables.\n","type":"(Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"fresh3","comment":" Create three lexically-scoped logic variables.\n","type":"(Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"fresh4","comment":" Create four lexically-scoped logic variables.\n","type":"(Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"fresh5","comment":" Create five lexically-scoped logic variables.\n","type":"(Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"fresh6","comment":" Create six lexically-scoped logic variables.\n","type":"(Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"fresh7","comment":" Create seven lexically-scoped logic variables.\n","type":"(Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"fresh8","comment":" Create eight lexically-scoped logic variables.\n","type":"(Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"ifte","comment":" `ifte` stands for **if-then-else**.\n\n`ifte g1 g2 g3` is a goal that applies `g1` to the current substitution. If `g1` succeeds, it applies `g2` to each of the\nsubstitutions produced by `g1`. If `g1` fails, it applies `g3` to the current substitution. Otherwise, if `g1` has no value,\nthe goal, `ifte g1 g2 g3`, also has no value.\n\n","type":"Logic.Goal.Goal a -> Logic.Goal.Goal a -> Logic.Goal.Goal a -> Logic.Goal.Goal a"},{"name":"lazy","comment":" Useful for defining recursive goals.\n\nFor e.g. here's a possible definition of [`always`](#always).\n\n    always : Goal a\n    always =\n        disj2 succeed (lazy (\\_ -> always))\n\n**Challenge:** Define [`never`](#never) using `lazy`.\n\n","type":"(() -> Logic.Goal.Goal a) -> Logic.Goal.Goal a"},{"name":"never","comment":" A goal that neither succeeds nor fails.\n","type":"Logic.Goal.Goal a"},{"name":"once","comment":" `once g` is a goal that applies `g` to the current substitution. If `g` succeeds, the first substitution produced by `g`\nis used to create a singleton stream which becomes the stream produced by `once g`. The remaining substitutions produced by `g`\nare dropped, i.e. we cutoff all other possibilities. If `g` fails, `once g` fails. And, if `g` has no value, `once g` also\nhas no value.\n","type":"Logic.Goal.Goal a -> Logic.Goal.Goal a"},{"name":"run","comment":" It's similar to [`runS`](#runS), except that for each substitution that would be in the list returned by `runS`,\nit reifies each substitution with a fresh variable.\n","type":"Logic.Goal.Length -> (Logic.Value.Value a -> Logic.Goal.Goal a) -> List.List (Logic.Value.Value a)"},{"name":"run2","comment":" It's similar to [`run`](#run), except that the value used for reification is a list containing two fresh variables.\n","type":"Logic.Goal.Length -> (Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> List.List (Logic.Value.Value a)"},{"name":"run3","comment":" It's similar to [`run`](#run), except that the value used for reification is a list containing three fresh variables.\n","type":"Logic.Goal.Length -> (Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> List.List (Logic.Value.Value a)"},{"name":"run4","comment":" It's similar to [`run`](#run), except that the value used for reification is a list containing four fresh variables.\n","type":"Logic.Goal.Length -> (Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> List.List (Logic.Value.Value a)"},{"name":"run5","comment":" It's similar to [`run`](#run), except that the value used for reification is a list containing five fresh variables.\n","type":"Logic.Goal.Length -> (Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> List.List (Logic.Value.Value a)"},{"name":"run6","comment":" It's similar to [`run`](#run), except that the value used for reification is a list containing six fresh variables.\n","type":"Logic.Goal.Length -> (Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> List.List (Logic.Value.Value a)"},{"name":"run7","comment":" It's similar to [`run`](#run), except that the value used for reification is a list containing seven fresh variables.\n","type":"Logic.Goal.Length -> (Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> List.List (Logic.Value.Value a)"},{"name":"run8","comment":" It's similar to [`run`](#run), except that the value used for reification is a list containing eight fresh variables.\n","type":"Logic.Goal.Length -> (Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Value.Value a -> Logic.Goal.Goal a) -> List.List (Logic.Value.Value a)"},{"name":"runS","comment":" Apply a goal to the empty substitution and return the list of substitutions produced by that goal.\n\nThe length of the list is determined by the argument of type [`Length`](#Length).\n\n","type":"Logic.Goal.Length -> Logic.Goal.Goal a -> List.List (Logic.Substitution.Substitution a)"},{"name":"succeed","comment":" A goal that succeeds only once, i.e. it produces a singleton stream containing\nthe current substitution. Contrast that with [`always`](#always).\n\n**N.B.** _The **current substitution** is the substitution that's passed to the goal._\n\n","type":"Logic.Goal.Goal a"},{"name":"toString","comment":" Convert a list of values to a representation that's useful for debugging and testing.\n","type":"(a -> String.String) -> List.List (Logic.Value.Value a) -> String.String"}],"binops":[]},{"name":"Logic.Stream","comment":" A combination of a list and a lazy list.\n\n@docs Stream\n\n\n# Create\n\n@docs singleton\n\n\n# Combine\n\n@docs append, appendMap\n\n\n# Convert\n\n@docs take, toList\n\n","unions":[{"name":"Stream","comment":" If you remove the `Suspend` constructor then you have a list.\n\n    type List a\n        = Empty\n        | Cons a (List a)\n\nIf you combine the `Cons` and `Suspend` constructors then you have a lazy list.\n\n    type LazyList a\n        = Empty\n        | Cons a (() -> LazyList a)\n\nNormal list streams:\n\n    Empty\n\n    Cons 3 Empty\n\n    Cons 2 (Cons 3 Empty)\n\n    Cons 1 (Cons 2 (Cons 3 Empty))\n\nPartial lazy list streams:\n\n    Suspend (\\_ -> Cons 1 (Cons 2 (Cons 3 Empty)))\n\n    Cons 1 (Cons 2 (Suspend (\\_ -> Cons 3 (Cons 4 (Suspend (\\_ -> Cons 5 Empty))))))\n\nA full lazy list stream:\n\n    Suspend (\\_ -> Cons 1 (Suspend (\\_ -> Cons 2 (Suspend (\\_ -> Cons 3 (Suspend (\\_ -> Empty)))))))\n\n","args":["a"],"cases":[["Empty",[]],["Cons",["a","Logic.Stream.Stream a"]],["Suspend",["() -> Logic.Stream.Stream a"]]]}],"aliases":[],"values":[{"name":"append","comment":" Put two streams together into one stream such that you will be able to eventually access any element from either stream,\nregardless if the first stream is infinite, the second stream is infinite, or both streams are infinite.\n\n    evensLessThan10 =\n        Cons 0 (Cons 2 (Cons 4 (Cons 6 (Cons 8 Empty))))\n\n    oddsLessThan10 =\n        Cons 1 (Cons 3 (Cons 5 (Cons 7 (Cons 9 Empty))))\n\n    take 10 (append evensLessThan10 oddsLessThan10) == [ 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 ]\n\n    arithmeticProgression a d =\n        Cons a <| Suspend (\\_ -> arithmeticProgression (a + d) d)\n\n    evens =\n        arithmeticProgression 0 2\n\n    odds =\n        arithmeticProgression 1 2\n\n    naturals =\n        append evens odds\n\n    take 10 (append evensLessThan10 odds) == [ 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 ]\n\n    take 10 (append evens oddsLessThan10) == [ 0, 1, 3, 5, 7, 9, 2, 4, 6, 8 ]\n\n    take 10 naturals == [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]\n\n**N.B.** _In the last example, the two infinite streams are completely interleaved. `append` is the basis upon which\nit is said that [miniKanren](https://minikanren.org/) uses a **complete interleaving search**._\n\n","type":"Logic.Stream.Stream a -> Logic.Stream.Stream a -> Logic.Stream.Stream a"},{"name":"appendMap","comment":" Map a function over a stream and [`append`](#append) the resulting streams.\n\n    repeat n =\n        Cons n <| Suspend (\\_ -> repeat n)\n\n    take 100 (appendMap repeat naturals) == [ 0, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0 ]\n\n    type alias Occurrences =\n        Int\n\n    statistics : List ( Int, Occurrences )\n    statistics =\n        [ ( 0, 53 )\n        , ( 1, 26 )\n        , ( 2, 12 )\n        , ( 3, 6 )\n        , ( 4, 2 )\n        , ( 5, 1 )\n        ]\n\n**N.B.** _It takes a while to get to each number but each number will eventually be reached, thanks to how [`append`](#append) works._\n\n","type":"(a -> Logic.Stream.Stream b) -> Logic.Stream.Stream a -> Logic.Stream.Stream b"},{"name":"singleton","comment":" Create a one element stream.\n","type":"a -> Logic.Stream.Stream a"},{"name":"take","comment":" Take the first `n` elements of a stream and put them into a list.\n","type":"Basics.Int -> Logic.Stream.Stream a -> List.List a"},{"name":"toList","comment":" Create a list of elements from a stream.\n\n    toList evensLessThan10 == [ 0, 2, 4, 6, 8 ]\n\n**N.B.** _It doesn't handle infinite streams. If you know your stream is infinite, use [`take`](#take) instead._\n\n","type":"Logic.Stream.Stream a -> List.List a"}],"binops":[]},{"name":"Logic.Substitution","comment":" A substitution is a mapping between variables and values.\n\nWe'll use the following variables and values throughout the examples in this module:\n\n    import Logic.Value exposing (..)\n    import Logic.Variable exposing (..)\n\n    u =\n        Variable \"u\" 0\n\n    v =\n        Variable \"v\" 1\n\n    w =\n        Variable \"w\" 2\n\n    x =\n        Variable \"x\" 3\n\n    y =\n        Variable \"y\" 4\n\n    z =\n        Variable \"z\" 5\n\n    vu =\n        Var u\n\n    vv =\n        Var v\n\n    vw =\n        Var w\n\n    vx =\n        Var x\n\n    vy =\n        Var y\n\n    vz =\n        Var z\n\n    five =\n        Const 5\n\n    a =\n        Const \"a\"\n\n    b =\n        Const \"b\"\n\n    c =\n        Const \"c\"\n\n    d =\n        Const \"d\"\n\n@docs Substitution\n\n\n# Unify\n\nThe **unification** of two values is the process of finding zero or more associations\nthat would make the two values equal.\n\n[`walk`](#walk), [`occurs`](#occurs), and [`extend`](#extend) are used to implement [`unify`](#unify).\n\n@docs walk, occurs, extend, unify\n\n\n# Reify\n\nReification is the process of removing all logic variables from a value.\n\n[`walkAll`](#walkAll) and [`reifiedNameSubstitution`](#reifiedNameSubstitution) are used to implement [`reify`](#reify).\n\n@docs walkAll, reifiedNameSubstitution, reify\n\n\n# Debug\n\n@docs toString\n\n","unions":[],"aliases":[{"name":"Substitution","comment":" A variable is allowed to be associated with another variable. If a variable that appears on\nthe left-hand side of an association never appears on the right-hand side of an association,\nthe substitution is called an **idempotent substitution**. Otherwise, it is called a\n**triangular substitution**.\n\nThe representation that's used allows for triangular substitutions.\n\nFor e.g.\n\n    [(y, five), (x, vy)]\n    -- is a triangular substitution\n\n    -- whereas,\n    [(y, five), (x, five)]\n    -- is an idempotent substitution\n\n","args":["a"],"type":"List.List ( Logic.Variable.Variable, Logic.Value.Value a )"}],"values":[{"name":"extend","comment":" Extend a substitution with a new association between a variable and a value.\n\n    extend u a [] == Just [ ( u, a ) ]\n\n    extend u a [ ( v, b ) ] == Just [ ( u, a ), ( v, b ) ]\n\nCycles aren't allowed.\n\n    extend x vy [ ( w, a ), ( z, vx ), ( y, vz ) ] == Nothing\n\n","type":"Logic.Variable.Variable -> Logic.Value.Value a -> Logic.Substitution.Substitution a -> Maybe.Maybe (Logic.Substitution.Substitution a)"},{"name":"occurs","comment":" Check whether or not the variable occurs within the value.\n\n    occurs u vv [] == False\n\n    occurs u vu [] == True\n\n    occurs x vy [ ( w, a ), ( z, vx ), ( y, vz ) ] == True\n\n    occurs x (Pair a (Pair vy Null)) [ ( z, vw ), ( y, Pair vx Null ) ] == True\n\n","type":"Logic.Variable.Variable -> Logic.Value.Value a -> Logic.Substitution.Substitution a -> Basics.Bool"},{"name":"reifiedNameSubstitution","comment":" A **reified-name** substitution is a substitution in which each fresh variable\nis mapped to a `ReifiedVar i` for some `i >= 0`.\n\n    reifiedNameSubstitution (Pair vx (Pair vy (Pair vx vz))) == [ ( z, ReifiedVar 2 ), ( y, ReifiedVar 1 ), ( x, ReifiedVar 0 ) ]\n\n","type":"Logic.Value.Value a -> Logic.Substitution.Substitution a"},{"name":"reify","comment":" Remove all logic variables from a value.\n\nThe fresh variables are replaced with reified variables.\n\n    corn =\n        Const \"corn\"\n\n    ice =\n        Const \"ice\"\n\n    substitution =\n        let\n            a1 =\n                -- `(,x . (,u ,w ,y ,z ((ice) ,z)))\n                ( x, Pair vu (Pair vw (Pair vy (Pair vz (Pair (Pair (Pair ice Null) (Pair vz Null)) Null)))) )\n\n            a2 =\n                -- `(,y . corn)\n                ( y, corn )\n\n            a3 =\n                -- `(,w . (,v ,u))\n                ( w, Pair vv (Pair vu Null) )\n        in\n        [ a1, a2, a3 ]\n\n    expectedValue =\n        let\n            u0 =\n                ReifiedVar 0\n\n            u1 =\n                ReifiedVar 1\n\n            u2 =\n                ReifiedVar 2\n        in\n        -- (_0 (_1 _0) corn _2 ((ice) _2))\n        Pair u0 (Pair (Pair u1 (Pair u0 Null)) (Pair corn (Pair u2 (Pair (Pair (Pair ice Null) (Pair u2 Null)) Null))))\n\n    reify vx substitution == expectedValue\n\n","type":"Logic.Value.Value a -> Logic.Substitution.Substitution a -> Logic.Value.Value a"},{"name":"toString","comment":" Convert to a representation that's useful for debugging and testing.\n\n    toString identity [] == \"()\"\n\n    toString identity [ ( u, vx ), ( v, a ), ( w, Pair b c ) ] == \"((u.0 . x.3) (v.1 . a) (w.2 . (b . c)))\"\n\n","type":"(a -> String.String) -> Logic.Substitution.Substitution a -> String.String"},{"name":"unify","comment":" Unifies two values with respect to a substitution.\n\nIt returns a, potentially extended, substitution if unification succeeds.\nOtherwise, it returns `Nothing` if unification fails or would introduce\na circularity.\n\n    unify vu a [] == Just [ ( u, a ) ]\n\n    unify a vu [] == Just [ ( u, a ) ]\n\n    unify vu vv [] == Just [ ( u, vv ) ]\n\n    unify vv vu [] == Just [ ( v, vu ) ]\n\n    unify vu vv [ ( w, b ), ( v, vw ) ] == Just [ ( u, b ), ( w, b ), ( v, vw ) ]\n\n    unify vu a [ ( u, a ) ] == Just [ ( u, a ) ]\n\n    unify vu b [ ( u, a ) ] == Nothing\n\n    value1 =\n        -- `(,x (,y))\n        Pair\n            vx\n            (Pair (Pair vy Null) Null)\n\n    value2 =\n        -- `((a b) (c))\n        Pair\n            (Pair a (Pair b Null))\n            (Pair (Pair c Null) Null)\n\n    expectedSubstitution =\n        -- `((,y . c) (,x . (a b)))\n        [ ( y, c )\n        , ( x, Pair a (Pair b Null) )\n        ]\n\n    unify value1 value2 [] == Just expectedSubstitution\n\n","type":"Logic.Value.Value a -> Logic.Value.Value a -> Logic.Substitution.Substitution a -> Maybe.Maybe (Logic.Substitution.Substitution a)"},{"name":"walk","comment":" Variable lookup.\n\n    sub1 = [ ( z, a ), ( x, vw ), ( y, vz ) ]\n\n    walk vz sub1 == a\n\n    walk vy sub1 == a\n\n    walk vx sub1 == vw\n\n    sub2 = [ ( x, vy ), ( v, vx ), ( w, vx ) ]\n\n    walk vx sub2 == vy\n\n    walk vv sub2 == vy\n\n    walk vw sub2 == vy\n\nIf the resulting value is a variable then the variable is fresh.\n\nA **fresh** variable is one that could be associated with any value.\n\n","type":"Logic.Value.Value a -> Logic.Substitution.Substitution a -> Logic.Value.Value a"},{"name":"walkAll","comment":" Walk all the variables contained within the value.\n\n    sub3 =\n        [ ( x, b )\n        , ( z, vy )\n        , ( w, Pair vx (Pair d (Pair vz Null)) )\n        ]\n\n    walk vw sub3 == Pair vx (Pair d (Pair vz Null))\n\nHowever,\n\n    walkAll vw sub3 == Pair b (Pair d (Pair vy Null))\n\nIf after walking all the variables contained within the value the resulting\nvalue still contains variables then those variables are fresh.\n\n","type":"Logic.Value.Value a -> Logic.Substitution.Substitution a -> Logic.Value.Value a"}],"binops":[]},{"name":"Logic.Value","comment":" Represents all the values (or terms) that can be associated with (logic) variables.\n\n@docs Value\n\n\n# Debug\n\n@docs toString\n\n","unions":[{"name":"Value","comment":" It is polymorphic in `a` so that you can specify your own constants.\n\n    type alias ValueS =\n        Value String\n\n    tea : ValueS\n    tea =\n        Const \"tea\"\n\nThe constant type can be as rich as you need it to be.\n\n","args":["a"],"cases":[["Const",["a"]],["Var",["Logic.Variable.Variable"]],["ReifiedVar",["Basics.Int"]],["Null",[]],["Pair",["Logic.Value.Value a","Logic.Value.Value a"]]]}],"aliases":[],"values":[{"name":"toString","comment":" Convert to a representation that's useful for debugging and testing.\n\n    u : ValueS\n    u =\n        Var (Variable \"u\" 0)\n\n    r : ValueS\n    r =\n        ReifiedVar 9\n\n    toString identity tea == \"tea\"\n\n    toString identity u == \"u.0\"\n\n    toString identity r == \"_9\"\n\n    toString identity Null == \"()\"\n\n    toString identity (Pair tea u) == \"(tea . u.0)\"\n\n    toString identity (Pair tea (Pair u (Pair r Null))) == \"(tea u.0 _9)\"\n\n    toString identity (Pair (Pair tea u) (Pair r Null)) == \"((tea . u.0) _9)\"\n\n","type":"(a -> String.String) -> Logic.Value.Value a -> String.String"}],"binops":[]},{"name":"Logic.Variable","comment":" Variables or logic variables.\n\n@docs Variable, Id\n\n\n# Debug\n\n@docs toString\n\n","unions":[],"aliases":[{"name":"Id","comment":" Any integral value can serve as an identifier.\n","args":[],"type":"Basics.Int"},{"name":"Variable","comment":" Variables are uniquely identified by their `name` and `id`.\n\n**N.B.** _The empty string name is reserved for use internally._\n\n","args":[],"type":"{ name : String.String, id : Logic.Variable.Id }"}],"values":[{"name":"toString","comment":" Convert to a representation that's useful for debugging and testing.\n\n    toString (Variable \"x\" 3) == \"x.3\"\n\n","type":"Logic.Variable.Variable -> String.String"}],"binops":[]}]