// Package strategy embeds Sun Tzu's Art of War as a structural layer in the // lattice. Strategic principles become both sticky elements (positive space) // and constraints (negative space), forming the system's permanent strategic // skeleton. // // The 13 chapters map to 13 strategic categories. Each category decomposes // into four levels: chapter, principle, maxim, and tactic. package strategy import ( _ "embed" "strings" ) //go:embed artofwar.txt var artOfWarText string // Category identifies one of the 13 strategic domains from The Art of War. type Category uint8 const ( CatAssessment Category = iota // I: Laying Plans CatResources // II: Waging War CatStratagem // III: Attack by Stratagem CatPositioning // IV: Tactical Dispositions CatMomentum // V: Energy CatExploitation // VI: Weak Points and Strong CatAdaptation // VII: Maneuvering CatFlexibility // VIII: Variation of Tactics CatSignalReading // IX: The Army on the March CatEnvironment // X: Terrain CatUrgency // XI: The Nine Situations CatForce // XII: The Attack by Fire CatIntelligence // XIII: The Use of Spies ) var categoryNames = [13]string{ "assessment", "resources", "stratagem", "positioning", "momentum", "exploitation", "adaptation", "flexibility", "signal-reading", "environment", "urgency", "force", "intelligence", } func (c Category) String() string { if int(c) < len(categoryNames) { return categoryNames[c] } return "unknown" } // Level distinguishes element granularity within a chapter. type Level uint8 const ( LevelChapter Level = iota // Whole chapter summary LevelPrinciple // Core principle (paragraph) LevelMaxim // Single maxim (sentence) LevelTactic // Tactical fragment (phrase) ) var levelNames = [4]string{"chapter", "principle", "maxim", "tactic"} func (l Level) String() string { if int(l) < len(levelNames) { return levelNames[l] } return "unknown" } // Maxim is a single strategic principle extracted from a chapter. type Maxim struct { Text string Chapter int Tags []string } // Chapter holds one of the 13 chapters of The Art of War. type Chapter struct { Number int Title string Category Category Text string // Full text of the chapter Maxims []Maxim // Extracted key principles } var chapters [13]Chapter // chapterDefs maps chapter markers to their metadata. var chapterDefs = [13]struct { marker string title string category Category }{ {"## I.", "Laying Plans", CatAssessment}, {"## II.", "Waging War", CatResources}, {"## III.", "Attack by Stratagem", CatStratagem}, {"## IV.", "Tactical Dispositions", CatPositioning}, {"## V.", "Energy", CatMomentum}, {"## VI.", "Weak Points and Strong", CatExploitation}, {"## VII.", "Maneuvering", CatAdaptation}, {"## VIII.", "Variation of Tactics", CatFlexibility}, {"## IX.", "The Army on the March", CatSignalReading}, {"## X.", "Terrain", CatEnvironment}, {"## XI.", "The Nine Situations", CatUrgency}, {"## XII.", "The Attack by Fire", CatForce}, {"## XIII.", "The Use of Spies", CatIntelligence}, } func init() { parseChapters() } // parseChapters splits the embedded text into 13 chapters and extracts maxims. func parseChapters() { lines := strings.Split(artOfWarText, "\n") // Find chapter boundaries. type boundary struct { line int idx int // index into chapterDefs } var bounds []boundary for i, line := range lines { for j, def := range chapterDefs { if strings.HasPrefix(line, def.marker) { bounds = append(bounds, boundary{i, j}) } } } for bi, b := range bounds { end := len(lines) if bi+1 < len(bounds) { end = bounds[bi+1].line } // Chapter text is everything after the heading line. var textLines []string for _, l := range lines[b.line+1 : end] { textLines = append(textLines, l) } text := strings.TrimSpace(strings.Join(textLines, "\n")) def := chapterDefs[b.idx] chapters[b.idx] = Chapter{ Number: b.idx + 1, Title: def.title, Category: def.category, Text: text, Maxims: extractMaxims(text, b.idx+1), } } } // extractMaxims identifies imperative and declarative maxims from chapter text. func extractMaxims(text string, chapter int) []Maxim { var maxims []Maxim // Split into sentences. sentences := splitSentences(text) for _, s := range sentences { s = strings.TrimSpace(s) if len(s) < 20 { continue } if isMaxim(s) { maxims = append(maxims, Maxim{ Text: s, Chapter: chapter, Tags: maximTags(s), }) } } return maxims } // splitSentences breaks text into sentences on period, exclamation, or // question mark boundaries that are followed by whitespace or end of text. func splitSentences(text string) []string { var sentences []string var current strings.Builder runes := []rune(text) for i, r := range runes { current.WriteRune(r) if (r == '.' || r == '!' || r == '?') && (i+1 >= len(runes) || runes[i+1] == ' ' || runes[i+1] == '\n') { s := strings.TrimSpace(current.String()) if s != "" { sentences = append(sentences, s) } current.Reset() } } if s := strings.TrimSpace(current.String()); s != "" { sentences = append(sentences, s) } return sentences } // isMaxim returns true if a sentence looks like a strategic principle. func isMaxim(s string) bool { lower := strings.ToLower(s) // Imperative indicators. imperatives := []string{ "must", "should", "therefore", "hence", "thus", "he who", "the general", "the skilful", "the skillful", "if you", "if your", "if he", "when you", "when the", "do not", "never", "always", "let ", "all warfare", "the art of war", "supreme excellence", "in war", "in battle", } for _, kw := range imperatives { if strings.Contains(lower, kw) { return true } } // Short declarative sentences are often maxims. if len(s) < 120 && !strings.Contains(s, "Sun Tz") { words := strings.Fields(s) if len(words) >= 4 && len(words) <= 25 { return true } } return false } // maximTags returns lattice-relevant tags for a maxim. func maximTags(s string) []string { lower := strings.ToLower(s) var tags []string tagKeywords := map[string][]string{ "deception": {"decep", "feign", "pretend", "appear", "seem"}, "speed": {"swift", "rapid", "quick", "haste", "speed"}, "patience": {"wait", "patient", "timing", "moment"}, "terrain": {"ground", "terrain", "position", "height"}, "intelligence": {"spy", "spies", "knowledge", "foreknowledge", "know"}, "resources": {"supply", "provision", "cost", "expenditure"}, "morale": {"spirit", "morale", "courage", "heart"}, "discipline": {"discipline", "order", "command", "obey"}, "adaptation": {"adapt", "change", "vary", "flexible", "modify"}, "force": {"attack", "strike", "fight", "battle", "force"}, } for tag, keywords := range tagKeywords { for _, kw := range keywords { if strings.Contains(lower, kw) { tags = append(tags, tag) break } } } return tags } // Chapters returns all 13 chapters. func Chapters() [13]Chapter { return chapters } // ChapterByNumber returns a chapter (1-13) or empty if out of range. func ChapterByNumber(n int) Chapter { if n < 1 || n > 13 { return Chapter{} } return chapters[n-1] }