package main

import "fmt"

type Vector [2]int

func before(a, b Vector) bool {
	less := false
	for i := range a {
		if a[i] > b[i] {
			return false
		}
		less = less || a[i] < b[i]
	}
	return less
}
func receive(local, message Vector, node int) Vector {
	for i := range local {
		local[i] = max(local[i], message[i])
	}
	local[node]++
	return local
}

type Op struct {
	Client     string
	Start, End int
	Write      bool
	Value      int
}

// Only completed operations on one register, initially zero. Bounded to 8 operations.
func validHistory(h []Op, realtime bool) bool {
	if len(h) > 8 {
		panic("bounded checker: at most 8 operations")
	}
	var visit func([]bool, int, int) bool
	visit = func(used []bool, depth, value int) bool {
		if depth == len(h) {
			return true
		}
		for i, op := range h {
			if used[i] {
				continue
			}
			blocked := false
			for j, prior := range h {
				if i == j || used[j] {
					continue
				}
				if (prior.Client == op.Client && prior.Start < op.Start) || (realtime && prior.End < op.Start) {
					blocked = true
				}
			}
			if blocked || (!op.Write && op.Value != value) {
				continue
			}
			next := value
			if op.Write {
				next = op.Value
			}
			used[i] = true
			if visit(used, depth+1, next) {
				return true
			}
			used[i] = false
		}
		return false
	}
	return visit(make([]bool, len(h)), 0, 0)
}
func main() {
	a, b := Vector{1, 0}, Vector{0, 2}
	fmt.Println("Lamport 1 < 2:", 1 < 2)
	fmt.Println("A before B:", before(a, b), "B before A:", before(b, a))
	merged := receive(b, a, 1)
	fmt.Println("B receives A:", merged, "A before receive:", before(a, merged))
	h := []Op{{"A", 1, 2, true, 1}, {"B", 3, 4, false, 0}}
	fmt.Println("sequential:", validHistory(h, false), "linearizable:", validHistory(h, true))
}
