Skip to main content

palaver-math

Dialogue and consensus mathematics — West African palaver tradition as iterative convergence, coalition formation, and dialogue trees.

What This Does

palaver-math models group decision-making as iterative consensus convergence, inspired by the West African palaver (community dialogue under a baobab tree). It provides sessions where participants hold position vectors, vote on proposals, and gradually converge toward consensus. It detects convergence rates, predicts final consensus positions, finds coalitions (clusters of nearby positions), and builds dialogue trees. Use it for multi-agent consensus, deliberative democracy simulations, collaborative filtering, or any scenario where distributed actors need to agree.

The Cultural Root

In many West African traditions, a palaver is a community gathering under a tree where disputes are resolved through dialogue until consensus is reached. There is no vote — discussion continues until everyone agrees. The mathematical insight: consensus is an iterative convergence process where each participant's position drifts toward the group center weighted by influence. This is identical to distributed averaging algorithms in computer science and opinion dynamics in statistical physics.

Install

pip install palaver-math

Quick Start

from palavermath.session import PalaverSession
from palavermath.consensus import compute_center, consensus_distance, influence_weighted_center
from palavermath.convergence import convergence_rate, is_converging
from palavermath.coalition import find_coalitions, coalition_strength
from palavermath.dialogue import build_dialogue_tree, find_consensus_path

# Start a consensus session
session = PalaverSession(threshold=0.5, step_size=0.1)

# Add participants with positions (e.g., 2D policy space)
p1 = session.add_participant(position=[1.0, 0.0])   # Conservative
p2 = session.add_participant(position=[0.0, 1.0])   # Progressive
p3 = session.add_participant(position=[0.5, 0.5])   # Moderate

# Add proposals and vote
prop = session.add_proposal(position=[0.4, 0.4])
session.vote(participant_idx=0, proposal_idx=0)  # Accepts → shifts position

# Run the full consensus loop
result = session.compute_consensus()
print(f"Consensus reached: {result['consensus_reached']}")
print(f"Center: {result['center']}")
print(f"Distance: {result['distance']}")
print(f"Rounds: {result['rounds']}")

# Check convergence
history = session.history()
rate = convergence_rate(history)
print(f"Converging: {is_converging(history)}")

# Find coalitions
participants = session.participants()
coalitions = find_coalitions(participants, threshold=0.8)
for c in coalitions:
    print(f"Coalition of {len(c)} participants, strength: {coalition_strength(c):.2f}")

# Dialogue tree
statements = [
    {"statement": "We should build the road", "parent_id": None},
    {"statement": "But what about the river?", "parent_id": 0},
    {"statement": "We can build a bridge", "parent_id": 1},
]
tree = build_dialogue_tree(statements)
path = find_consensus_path(tree)

API Reference

session module

PalaverSession

class PalaverSession:
    def __init__(self, threshold=1.0, step_size=0.1, max_rounds=1000)
    def add_participant(self, position) → int  # Returns participant index
    def add_proposal(self, position) → int     # Returns proposal index
    def vote(self, participant_idx, proposal_idx) → None
    def compute_consensus(self) → dict  # {consensus_reached, center, distance, rounds, positions}
    def participants(self) → list[dict]
    def history(self) → list  # history[round][participant][dim]
    def round(self) → int

consensus module

compute_center(participants) → list[float]

Geometric centroid of participant positions.

consensus_distance(participants) → float

Average Euclidean distance from each participant to the center. Measures spread: 0 = perfect agreement.

influence_weighted_center(participants, weights=None) → list[float]

Weighted centroid where participants may carry different influence.

convergence module

convergence_rate(session_history) → float

Average per-step change in consensus distance. Negative = converging.

predict_consensus(session, max_steps=100) → list[float]

Predict where the session will converge by running the convergence loop.

is_converging(session_history) → bool

True if the last few rounds show decreasing consensus distance.

coalition module

find_coalitions(participants, threshold) → list[list]

Groups where every pair is within threshold distance (single-linkage clustering).

coalition_strength(coalition) → float

0–1 cohesion score. 1.0 = everyone shares the same position.

merge_adjacent(coalitions, threshold) → list[list]

Merge coalitions whose centroids are within threshold.

dialogue module

DialogueNode

@dataclass
class DialogueNode:
    statement: str
    responses: list[DialogueNode]
    depth: int

build_dialogue_tree(statements) → DialogueNode

Build a tree from flat statement records with statement, parent_id, responses.

find_consensus_path(tree) → list[DialogueNode]

Shortest root-to-leaf path (BFS). Consensus = reaching a leaf.

How It Works

Consensus Session: Each participant holds a position vector. When a participant accepts a proposal, their position shifts toward the proposal by step_size. The session runs rounds until consensus distance drops below threshold or max_rounds is hit.

Convergence: Tracks the average distance from all participants to the geometric center over time. If this distance is decreasing, the group is converging.

Coalitions: Uses single-linkage clustering — two participants are in the same coalition if any path of within-threshold hops connects them.

Dialogue Trees: Statements form a tree. Consensus path = shortest root-to-leaf path, representing the most efficient route to a conclusion.

The Math

Consensus Distance: D = (1/n) Σᵢ ||pᵢ − c|| where c = (1/n) Σᵢ pᵢ is the centroid.

Position Update: pᵢ(t+1) = pᵢ(t) + α · (q − pᵢ(t)) where q is the accepted proposal and α is the step size. This is gradient descent toward the proposal.

Convergence Rate: r = (1/T) Σₜ (D(t+1) − D(t)). Negative r means converging.

Coalition Strength: s = 1 − (1/(k·d_max)) Σᵢ<ⱼ ||pᵢ − pⱼ|| normalized to [0, 1].

License

MIT

Metadata

Release files for palaver-math 0.1.0

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

Source distribution (sdist)

Source distribution for palaver-math 0.1.0
File Size Uploaded Provenance Actions
palaver_math-0.1.0.tar.gz 13.0 kB Without provenance Details for palaver_math-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for palaver-math 0.1.0
File Interpreter ABI Platform Actions
palaver_math-0.1.0-py3-none-any.whl Python 3 none any Details for palaver_math-0.1.0-py3-none-any.whl

Total release size: 25.7 kB

Release files / palaver_math-0.1.0.tar.gz

Download URL palaver_math-0.1.0.tar.gz
Size 13.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c962127549a2f72afdfa7bfea58308832ba945e98b8c62447ca7c081d63bb962
BLAKE2b-256 checksum
How to use checksums
7bc11687eda2b3976d81edc794e587b6a910c6b25513ec1afdc1222e2daf93db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.12

Release files / palaver_math-0.1.0-py3-none-any.whl

Download URL palaver_math-0.1.0-py3-none-any.whl
Size 12.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ec406f34fd9503d2909bbec7897397fa311c62b90fc47988c49c6eecf808aab8
BLAKE2b-256 checksum
How to use checksums
da8b90fb2960ccc7cc7c8aeb86ca2524125a4d39ef1929a5a623b6f360661b3e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.12

Security for palaver-math 0.1.0

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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

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