Skip to main content

Pinochle - Core Library

Python implementation of the Nock 4K Combinator Calculus.

Components

Installation

pip install pinochle

Or from source:

git clone https://github.com/sigilante/pinochle.git
cd pinochle/packages/pinochle
pip install .

Usage

from pinochle import nock, parse_noun

# Parse and evaluate Nock expressions
result = nock(42, parse_noun("[0 1]"))
print(result)  # 42

# Increment
result = nock(41, parse_noun("[4 0 1]"))
print(result)  # 42

Terms (%tas)

The parser accepts Hoon-style % constants alongside numbers. % before a number is that number (an atom is already a constant); % before a term (a-z, -, ., …) is the term's bytes as a little-endian atom — the @tas cord. Number syntax (with . digit separators) is unchanged.

from pinochle import parse

parse('%dec')        # 6514020   (little-endian cord for "dec")
parse('%42')         # 42
parse('[%fast %dec]')# Cell(1953718630, 6514020)
parse('1.024')       # 1024

Jets and hints

A jet is a native Python implementation of a Nock arm, matched by the mug of a core's battery — the register-then-match architecture Vere uses, minus parents and hooks.

A %fast opcode-11 hint wraps a core-producing formula:

*[a 11 [%fast name] core-formula]  ==  *[a core-formula]

It is transparent — it just produces the core — but as a side effect it warms the core's battery: it records mug(battery) → native in a run-time table, where the native is looked up by name (a @tas cord such as %dec, or an Urbit-style [name parent hooks] clue whose head is the name; the clue is metadata, never evaluated as a formula).

Dispatch happens at arm invocation (Nock 9). Evaluating *[a 9 b c] builds the core *[a c]; if its battery is warm, the native runs against the core instead of the arm formula. A native receives the whole core [battery payload]; for a gate the sample is at axis 6 and the context at axis 7 (the standard Hoon calling convention). With jets disabled, or an unregistered name/battery, nothing warms and nothing dispatches — results are identical, so a jet only changes cost, never meaning.

from pinochle import nock, parse, to_noun, register_jet, jets, Cell

# A native reads the sample from the core at +6.  The built-ins
# (dec/add/sub/mul/lte) follow the same convention; register your own by name.
register_jet('inc', lambda core: int(core.tail.head) + 1)

# A minimal inc gate: core = [battery [sample context]], battery [4 0 6].
core = to_noun(((4, 0, 6), (5, 0)))

# %fast warms the battery and returns the core (transparent)...
nock(0, Cell(11, Cell(Cell(jets.cord('fast'), jets.cord('inc')), Cell(1, core))))
# ...so invoking arm 2 now dispatches the native instead of the formula:
nock(core, parse('[9 2 0 1]'))           # 6

# Certification: run BOTH native and arm formula on every dispatch, assert equal.
jets.VALIDATE = True
# Master switch (nothing warms, nothing dispatches — pure interpreter):
jets.ENABLED = False
jets.reset_warm()                        # clear the run-time warm table

pinochle is an interpreter, not a compiler: it emits no hints. Jets fire only on cores warmed by [11 [%fast name] core] hints present in the noun (for example those produced by nockasm's (%hintd 'fast' 'dec' …)). Dispatch keys on the battery mug alone, so it assumes one jet per battery (true for gates, not multi-arm cores) and, being a 31-bit mug, could in principle collide (astronomically unlikely).

A runnable end-to-end demo — the built-in %dec native accelerating the genuine O(n) Nock decrement loop, with jets off, jets on, and VALIDATE all agreeing — is in examples/jets_demo.py:

python examples/jets_demo.py
#   dec 7
#     jets off (formula) : 6
#     jets on  (native)  : 6
#     VALIDATE (both=)   : 6
#     ok: native and formula agree

Debug hints (%slog, %bout)

The dynamic hint [11 [%slog clue] body] prints its clue ([priority tank]) before producing body, the Nock analogue of Hoon's ~&. The static hint [11 %bout body] times the evaluation of body and reports the elapsed time, Urbit's ~>(%bout .). Both stay transparent — the body's value is unchanged — and both write to stderr by default through a redirectable sink:

from pinochle import jets

# route ~& output into a Jupyter cell instead of the server's stderr
jets.SLOG = lambda clue: my_stream_writer(clue)

# collect timings instead of printing them (elapsed is in nanoseconds)
jets.BOUT = lambda elapsed_ns: timings.append(elapsed_ns)

API Reference

See full documentation in the repository.

License

MIT License

Metadata

Release files for pinochle 1.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pinochle 1.3.1
File Size Uploaded Provenance Actions
pinochle-1.3.1.tar.gz 20.3 kB Without provenance Details for pinochle-1.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pinochle 1.3.1
File Interpreter ABI Platform Actions
pinochle-1.3.1-py3-none-any.whl Python 3 none any Details for pinochle-1.3.1-py3-none-any.whl

Total release size: 41.1 kB

Release files / pinochle-1.3.1.tar.gz

Download URL pinochle-1.3.1.tar.gz
Size 20.3 kB
Tags Source
SHA-256 checksum
How to use checksums
737fca35e350c088dda3ffa3e8bca11b4f44b83f5b27b0a9191ddd49d81b3a27
BLAKE2b-256 checksum
How to use checksums
4904bc50fbc9ccdd96cfadaa3abde8748ee24a42a0665e032b4d77721894047e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Release files / pinochle-1.3.1-py3-none-any.whl

Download URL pinochle-1.3.1-py3-none-any.whl
Size 20.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
029a3faf708d0aa7d1d8d59f5a9c4000c128a27a7b2001f519c6459928865cd0
BLAKE2b-256 checksum
How to use checksums
eca862c176ddbe0783ad9c94fdf36225ca139803e3806a0bca099857767d8be7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.7

Security for pinochle 1.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page