Skip to content

Unix CLI Guide

FuzzyInfer embraces the Unix philosophy with composable command-line tools.

Philosophy

FuzzyInfer follows Unix principles:

  1. Do One Thing Well - Each command has a single purpose
  2. Text Streams - JSONL for universal compatibility
  3. Composability - Combine with any JSON-aware tool
  4. Silence is Golden - No unnecessary output

Installation

# Install with CLI support
pip install "fuzzy-infer[cli]"

# Verify installation
fuzzy-infer --version

Basic Usage

Command Structure

fuzzy-infer [OPTIONS] COMMAND [ARGS]

# Get help
fuzzy-infer --help
fuzzy-infer COMMAND --help

Core Commands

Command Purpose
run Execute inference on facts/rules
query Filter facts by pattern
repl Interactive shell
validate Check JSONL syntax
convert Transform between formats

JSONL Format

FuzzyInfer uses JSON Lines (one JSON object per line):

Fact Format

{"type": "fact", "pred": "is-bird", "args": ["robin"], "degree": 0.9}
{"type": "fact", "pred": "has-wings", "args": ["robin"], "degree": 1.0}

Rule Format

{
  "type": "rule",
  "name": "bird-can-fly",
  "when": [{"pred": "is-bird", "args": ["?x"]}],
  "then": [{"action": "add", "pred": "can-fly", "args": ["?x"], "degree": 0.85}]
}

Running Inference

Basic Inference

# Run inference on files
fuzzy-infer run facts.jsonl rules.jsonl

# Stream from stdin
cat facts.jsonl | fuzzy-infer run rules.jsonl

# Multiple rule files
fuzzy-infer run facts.jsonl rules1.jsonl rules2.jsonl

Options

# Limit iterations
fuzzy-infer run --max-iter 10 facts.jsonl rules.jsonl

# Output only new facts
fuzzy-infer run --new-only facts.jsonl rules.jsonl

# Debug mode
fuzzy-infer run --debug facts.jsonl rules.jsonl

Querying Facts

Pattern Matching

# Query all facts of a predicate
fuzzy-infer query "is-bird"

# Query with arguments
fuzzy-infer query "is-bird robin"

# Pattern variables
fuzzy-infer query "parent ?x charlie"  # Who is charlie's parent?

Filtering

# Minimum degree
fuzzy-infer query --min-degree 0.8 "can-fly"

# Maximum results
fuzzy-infer query --limit 10 "is-mammal"

# Sort by degree
fuzzy-infer query --sort "confidence"

Unix Pipelines

With jq

# Extract high-confidence facts
cat facts.jsonl |
fuzzy-infer run rules.jsonl |
jq 'select(.degree > 0.8)'

# Count facts by predicate
fuzzy-infer query |
jq -r '.pred' |
sort | uniq -c

# Transform to CSV
fuzzy-infer query "temperature" |
jq -r '[.args[0], .args[1], .degree] | @csv'

With grep and awk

# Find specific patterns
fuzzy-infer query |
grep '"pred":"is-bird"'

# Extract degrees
fuzzy-infer query "confidence" |
awk -F'"degree":' '{print $2}' |
awk -F'}' '{print $1}' |
sort -n

Chaining Inference

# Multi-stage inference
cat initial_facts.jsonl |
fuzzy-infer run stage1_rules.jsonl |
fuzzy-infer run stage2_rules.jsonl |
fuzzy-infer query "final-classification"

Interactive REPL

Starting REPL

fuzzy-infer repl

# With initial data
fuzzy-infer repl --load knowledge.jsonl

REPL Commands

> fact is-bird robin 0.9
Added: is-bird(robin) = 0.9

> rule bird-fly: is-bird ?x -> can-fly ?x 0.85
Added rule: bird-fly

> infer
Inference complete. 1 new facts added.

> query can-fly
can-fly(robin) = 0.765

> save session.jsonl
Saved 2 facts and 1 rules

> help
Available commands: fact, rule, infer, query, save, load, clear, exit

Advanced REPL

> fact temperature sensor1 25.5
> rule hot: temperature ?s ?t & ?t > 30 -> alert ?s high
> watch temperature  # Monitor changes
> explain can-fly robin  # Show derivation

File Formats

Converting Formats

# YAML to JSONL
fuzzy-infer convert rules.yaml --output rules.jsonl

# CSV to JSONL
fuzzy-infer convert facts.csv --type facts --output facts.jsonl

# Pretty print JSONL
fuzzy-infer convert facts.jsonl --pretty

Validation

# Validate JSONL syntax
fuzzy-infer validate knowledge.jsonl

# Validate with schema
fuzzy-infer validate --strict facts.jsonl

# Check for conflicts
fuzzy-infer validate --check-conflicts facts.jsonl rules.jsonl

Streaming

Continuous Processing

# Process sensor stream
tail -f sensor_data.jsonl |
fuzzy-infer run rules.jsonl --stream |
tee processed.jsonl |
fuzzy-infer query "alert" --stream

Windowed Processing

# Process in time windows
fuzzy-infer run rules.jsonl \
  --window 60 \
  --slide 10 \
  < stream.jsonl

Performance

Parallel Processing

# Split and process in parallel
split -l 1000 large_facts.jsonl part_

parallel -j 4 'fuzzy-infer run rules.jsonl < part_{} > out_{}' ::: a*

cat out_* | fuzzy-infer dedupe

Profiling

# Time inference
time fuzzy-infer run facts.jsonl rules.jsonl > /dev/null

# Memory usage
/usr/bin/time -v fuzzy-infer run large.jsonl rules.jsonl

# Profile output
fuzzy-infer run --profile facts.jsonl rules.jsonl

Advanced Usage

Environment Variables

# Set default options
export FUZZY_INFER_DEBUG=1
export FUZZY_INFER_MAX_ITER=100
export FUZZY_INFER_FORMAT=pretty

fuzzy-infer run facts.jsonl rules.jsonl

Configuration File

# Use config file
fuzzy-infer --config ~/.fuzzyinfer.toml run facts.jsonl

# Config format (TOML)
cat ~/.fuzzyinfer.toml
[defaults]
max_iter = 100
debug = false
format = "jsonl"

[fuzzy]
t_norm = "min"
t_conorm = "max"

Shell Integration

# Bash completion
eval "$(fuzzy-infer --bash-completion)"

# Zsh completion
fuzzy-infer --zsh-completion > ~/.zsh/completions/_fuzzy-infer

# Fish completion
fuzzy-infer --fish-completion > ~/.config/fish/completions/fuzzy-infer.fish

Real-World Examples

Log Analysis

# Convert logs to facts
grep ERROR app.log |
awk '{print "{\"type\":\"fact\",\"pred\":\"error\",\"args\":[\"" $4 "\",\"" $5 "\"],\"degree\":1.0}"}' |
fuzzy-infer run error_rules.jsonl |
fuzzy-infer query "critical-issue"

Monitoring Pipeline

# System monitoring
while true; do
  # Collect metrics
  echo "{\"type\":\"fact\",\"pred\":\"cpu-usage\",\"args\":[\"$(hostname)\",$(top -n1 | grep Cpu | awk '{print $2}')],\"degree\":1.0}"
  echo "{\"type\":\"fact\",\"pred\":\"memory\",\"args\":[\"$(hostname)\",$(free -m | awk 'NR==2{printf "%.1f", $3*100/$2}')],\"degree\":1.0}"
done |
fuzzy-infer run monitoring_rules.jsonl --stream |
fuzzy-infer query "alert" --stream |
xargs -I {} sh -c 'echo {} | mail -s "System Alert" admin@example.com'

Data Classification

# Classify records
cat customer_data.jsonl |
parallel --pipe -N 1000 'fuzzy-infer run classification_rules.jsonl' |
fuzzy-infer query "category" |
jq -s 'group_by(.args[1]) | map({category: .[0].args[1], count: length})'

Tips and Tricks

Debugging

# Verbose output
fuzzy-infer run -vv facts.jsonl rules.jsonl 2>&1 | less

# Trace specific rules
fuzzy-infer run --trace rule-name facts.jsonl rules.jsonl

# Dry run
fuzzy-infer run --dry-run facts.jsonl rules.jsonl

Optimization

# Index facts for faster queries
fuzzy-infer index facts.jsonl --output facts.idx
fuzzy-infer query --index facts.idx "complex-pattern"

# Cache inference results
fuzzy-infer run --cache /tmp/fuzzy-cache facts.jsonl rules.jsonl

Integration

# Docker container
docker run -i fuzzy-infer run rules.jsonl < facts.jsonl

# Kubernetes job
kubectl create job inference --image=fuzzy-infer -- run /data/rules.jsonl

# AWS Lambda
aws lambda invoke --function fuzzy-inference --payload @facts.jsonl output.json

Common Patterns

Rule Testing

# Test single rule
echo '{"type":"fact","pred":"is-bird","args":["test"],"degree":1.0}' |
fuzzy-infer run <(echo '{"type":"rule","when":[{"pred":"is-bird","args":["?x"]}],"then":[{"action":"add","pred":"can-fly","args":["?x"]}]}')

Fact Generation

# Generate test facts
seq 1 100 |
xargs -I {} echo '{"type":"fact","pred":"item","args":["item{}",{}],"degree":1.0}'

Result Aggregation

# Aggregate degrees
fuzzy-infer query "confidence" |
jq -s '[.[].degree] | add/length'

Next Steps