PHPackages                             igorw/reasoned - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. igorw/reasoned

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

igorw/reasoned
==============

A miniKanren in PHP.

75115Hack

Since Jan 3Pushed 11y ago5 watchersCompare

[ Source](https://github.com/igorw/reasoned-php)[ Packagist](https://packagist.org/packages/igorw/reasoned)[ RSS](/packages/igorw-reasoned/feed)WikiDiscussions master Synced 6d ago

READMEChangelogDependenciesVersions (1)Used By (0)

reasoned-php
============

[](#reasoned-php)

A [miniKanren](http://minikanren.org/) in PHP.

Prologue
--------

[](#prologue)

What the hell is this? It's a tiny logic programming engine!

What is logic programming, you ask? Logic programming is a largely underrated paradigm that radically changes the way you write, think about, and run, programs.

Imagine your program as a bunch of relations. You can relate things to each other. Every time you would use an uni-directional assignment `=`, that assignment now becomes a bi-directional relation `==`. It goes both ways. The program forms a chain of relations from one or more inputs to one or more outputs.

You can introduce logic variables that are unbound values (using `fresh`). These variables obey the constraints imposed on them through relations. This allows you to provide a fresh logic variable and see what it gets bound to. That's what you generally do to get an output from a logic program.

Through the use of conjunction ("and") and disjunction ("or"), you can form logical relations. This allows you to encode different possible flows of execution. The higher-level method for this is `conde`, which is a disjunction of conjunctions.

All of these logical relations form a tree. The execution of a program corresponds to a breadth-first search through the tree that unifies the provided arguments in accordance to the relations. This means that a program can discover more than one solution, or no solution at all.

This radical way of thinking about and writing programs allows for something very amazing: **You can run your programs backwards.**

What this means is that you can either give a program inputs and search for a corresponding output, but you can also provide outputs and ask for corresponding inputs.

Examples
--------

[](#examples)

### eq

[](#eq)

```
var_dump(run_star(function ($q) {
    return eq($q, 'corn');
}));

// => ['corn']

```

### conde

[](#conde)

```
var_dump(run_star(function ($q) {
    return conde([
        [eq($q, 'tea')],
        [eq($q, 'cup')],
    ]);
}));

// => ['tea', 'cup']

```

### firsto

[](#firsto)

```
var_dump(run_star(function ($q) {
    return firsto(['a', 'c', 'o', 'r', 'n'], $q);
}));

// => ['a']

```

### resto

[](#resto)

```
var_dump(run_star(function ($q) {
    return resto(['a', 'c', 'o', 'r', 'n'], $q);
}));

// => [['c', 'o', 'r', 'n']]

```

### all

[](#all)

```
var_dump(run_star(function ($q) {
    return all([
        firsto(['a', 'l'], $q),
        firsto(['a', 'x'], $q),
        firsto(['a', 'z'], $q),
    ]);
}));

// => ['a']

```

### fresh

[](#fresh)

```
var_dump(run_star(function ($q) {
    return fresh(function ($x) use ($q) {
        return all([
            eq(['d', 'a', $x, 'c'], $q),
            conso($x, ['a', $x, 'c'], $q),
        ]);
    });
}));

// => ['d', 'a', 'd', 'c']

```

### membero

[](#membero)

```
function membero($x, $l) {
    return conde([
        [fresh(function ($d) use ($x, $l) {
            return conso($x, $d, $l);
         })],
        [fresh(function ($a, $d) use ($x, $l) {
            return all([
                conso($a, $d, $l),
                membero($x, $d),
            ]);
         })],
    ]);
}

var_dump(run_star(function ($q) {
    return all([
        membero($q, [1, 2, 3]),
        membero($q, [2, 3, 4]),
    ]);
}));

// => [2, 3]

```

### run

[](#run)

```
var_dump(run(3, function ($q) {
    return membero('tofu', $q);
}));

// => [['tofu', '.', '_.0']
//     ['_.0', 'tofu', '.', '_.1']
//     ['_.0', '_.1', 'tofu', '.', '_.2']]

```

### appendo

[](#appendo)

```
var_dump(run_star(function ($q) {
    return appendo([1, 2, 3], [4, 5, 6], $q);
}));

// => [[1, 2, 3, 4, 5, 6]]

```

### neq (disequality)

[](#neq-disequality)

```
var_dump(run_star(function ($q) {
    return all([
        membero($q, [1, 2, 3]),
        neq($q, 2),
    ]);
}));

// => [1, 3]

```

### rembero

[](#rembero)

```
function rembero($x, $l, $out) {
    return conde([
        [eq([], $l), eq([], $out)],
        [fresh(function ($a, $d) use ($x, $l, $out) {
            return all([
                eq(pair($a, $d), $l),
                eq($a, $x),
                eq($d, $out),
            ]);
         })],
        [fresh(function ($a, $d, $res) use ($x, $l, $out) {
            return all([
                eq(pair($a, $d), $l),
                neq($a, $x),
                eq(pair($a, $res), $out),
                rembero($x, $d, $res),
            ]);
         })],
    ]);
}

var_dump(run_star(function ($q) {
    return rembero('b', ['a', 'b', 'c', 'b', 'd'], $q);
}));

// => [['a', 'c', 'b', 'd']]

```

See also
--------

[](#see-also)

- [The Reasoned Schemer](http://mitpress.mit.edu/books/reasoned-schemer)
- [miniKanren](http://minikanren.org/)
- [miniKanren](https://scholarworks.iu.edu/dspace/bitstream/handle/2022/8777/Byrd_indiana_0093A_10344.pdf) (Byrd's Dissertation)
- [microKanren](http://webyrd.net/scheme-2013/papers/HemannMuKanren2013.pdf)
- [rKanren](http://webyrd.net/scheme-2013/papers/Swords2013.pdf)
- [Clause and Effect](http://www.amazon.com/Clause-Effect-Programming-Working-Programmer/dp/3540629718) by William F. Clocksin

###  Health Score

25

—

LowBetter than 37% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity19

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 99.1% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/3afcc18d00fff840775bbf9570b3e9cd3997ca4820b9bfb14caf6da3ae580370?d=identicon)[igorw](/maintainers/igorw)

---

Top Contributors

[![igorw](https://avatars.githubusercontent.com/u/88061?v=4)](https://github.com/igorw "igorw (106 commits)")[![wouterj](https://avatars.githubusercontent.com/u/749025?v=4)](https://github.com/wouterj "wouterj (1 commits)")

### Embed Badge

![Health badge](/badges/igorw-reasoned/health.svg)

```
[![Health](https://phpackages.com/badges/igorw-reasoned/health.svg)](https://phpackages.com/packages/igorw-reasoned)
```

###  Alternatives

[parsecsv/php-parsecsv

CSV data parser for PHP

6885.7M38](/packages/parsecsv-php-parsecsv)[kyslik/column-sortable

Package for handling column sorting in Laravel 6.x

6485.6M21](/packages/kyslik-column-sortable)[sensiolabs/ansi-to-html

A library to convert a text with ANSI codes to HTML

2537.8M53](/packages/sensiolabs-ansi-to-html)[dflydev/dot-access-configuration

Given a deep data structure representing a configuration, access configuration by dot notation.

13414.5M4](/packages/dflydev-dot-access-configuration)[stfalcon/tinymce-bundle

This Bundle integrates TinyMCE WYSIWYG editor into a Symfony2 project.

2692.9M24](/packages/stfalcon-tinymce-bundle)[b13/container

Create Custom Container Content Elements for TYPO3

1823.1M63](/packages/b13-container)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
