Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ makedocs(;
"Rydberg Gadgets on Triangular Lattice" => "generated/trangular_Rydberg_example.md",
"QUBO Gadgets on Triangular Lattice" => "generated/triangular_QUBO_example.md",
],
"Unweighted Search" => "unweighted_search.md",
"Reference" => "ref.md",
],
)
Expand Down
5 changes: 5 additions & 0 deletions docs/src/unweighted_search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Dynamic unweighted search
`search_unweighted_gadgets` builds planar logical graphs, applies exact vertex
splits and even subdivisions, and embeds them on KSG or triangular lattices.
`is_gadget_replacement` remains final; four-pin results also pass G1--G4.
`result.trace` stores edge lists and rewrite actions, never graph6 identifiers.
63 changes: 25 additions & 38 deletions examples/pr1_crossing_pipeline.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# # PR1 Crossing Pipeline (line-by-line runnable)
#
# This script demonstrates two parts of the unweighted crossing workflow:
# 1) logical flip utilities
# 2) search_unweighted_gadgets
# This script demonstrates the unweighted crossing search workflow.
#
# It is intentionally organized into small, single-purpose functions so users can
# execute each section line by line in the REPL and inspect output immediately.

using GadgetSearch
using Graphs
using GenericTensorNetworks: content
using Random

const OUTPUT_DIR = pkgdir(GadgetSearch, "examples", "pr1_pipeline_output")

Expand Down Expand Up @@ -43,40 +41,31 @@ function plot_found_replacement(g::SimpleGraph{Int})
return path
end

function run_flip_demo(target_graph::SimpleGraph{Int}, target_boundary::Vector{Int})
println("\n=== Module: flip ===")
reduced = Float64.(content.(calculate_reduced_alpha_tensor(target_graph, target_boundary)))
patterns = generate_flip_patterns(length(target_boundary))
println("Flip patterns: $(length(patterns))")
for (mask, desc) in patterns
flipped = apply_flip_to_tensor(reduced, mask)
finite_deltas = [f - b for (f, b) in zip(vec(flipped), vec(reduced)) if isfinite(f) && isfinite(b)]
example_delta = isempty(finite_deltas) ? "n/a" : string(first(finite_deltas))
println(" $desc, mask=$mask, finite_delta_example=$example_delta")
end
end

function build_loader_from_candidates(candidate_graphs::Vector{SimpleGraph{Int}}, target_boundary::Vector{Int})
isempty(candidate_graphs) && throw(ArgumentError("candidate_graphs must be non-empty"))
dataset = GraphDataset(graph_to_g6.(candidate_graphs))
return GraphLoader(dataset, pinset=target_boundary)
end

function run_search_demo(target_graph::SimpleGraph{Int}, target_boundary::Vector{Int}, candidate_graphs::Vector{SimpleGraph{Int}})
function run_search_demo(target_graph::SimpleGraph{Int}, target_boundary::Vector{Int})
println("\n=== Module: search ===")
loader = build_loader_from_candidates(candidate_graphs, target_boundary)
results = search_unweighted_gadgets(
report = search_unweighted_gadgets(
target_graph,
target_boundary,
loader;
include_logical_flips=true,
max_results=10,
Square();
min_vertices=5,
max_vertices=17,
max_evaluations=400,
beam_width=32,
mutations_per_candidate=8,
random_candidates_per_generation=8,
max_results=4,
rng=MersenneTwister(2),
)
println("Search hits: $(length(results))")
for (i, result) in enumerate(results)
println(" hit[$i]: boundary=$(result.boundary_vertices), offset=$(result.constant_offset), vertices=$(nv(result.replacement_graph))")
println("Evaluated: $(report.evaluated) candidates in $(report.generations) generations")
println("Termination: $(report.termination_reason)")
println("Best distance: mask mismatches=$(report.best_mask_mismatches), offset spread=$(report.best_offset_spread)")
println("Search hits: $(length(report.gadgets))")
for (i, result) in enumerate(report.gadgets)
println(" hit[$i]: lattice=$(result.lattice), coordinates=$(result.lattice_coordinates)")
println(" boundary=$(result.boundary_vertices), rays=$(result.pin_rays)")
println(" offset=$(result.constant_offset), vertices=$(nv(result.replacement_graph))")
end
return results
return report
end

if abspath(PROGRAM_FILE) == @__FILE__
Expand All @@ -90,12 +79,10 @@ if abspath(PROGRAM_FILE) == @__FILE__
print_graph_summary("canonical", target_graph)
plot_canonical_crossing(target_graph)

run_flip_demo(target_graph, target_boundary)
candidates = [target_graph]
results = run_search_demo(target_graph, target_boundary, candidates)
report = run_search_demo(target_graph, target_boundary)

if !isempty(results)
plot_found_replacement(results[1].replacement_graph)
if !isempty(report.gadgets)
plot_found_replacement(report.gadgets[1].replacement_graph)
end

println("\nDone. You can now inspect outputs in: $OUTPUT_DIR")
Expand Down
3 changes: 3 additions & 0 deletions src/GadgetSearch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ export is_gadget_replacement

# Unweighted search
export UnweightedGadget
export UnweightedSearchResult
export UnweightedSearchRecord
export search_unweighted_gadgets
export check_crossing_frame

end # module
Loading
Loading