echoes 0.12.0

Find duplicated Rust doctests, functions and contexts
Documentation
//! Exhaustive small graph comparison through the public API.

use std::collections::BTreeMap;
use std::fmt::Write as _;

#[path = "support/dependency_value_oracle.rs"]
mod value_oracle;
use value_oracle::{Value, operation};

#[path = "support/permutations.rs"]
mod permutations;
use permutations::permutations;

#[derive(Clone, Copy)]
enum Producer {
    Argument(usize),
    Previous(usize),
    Pair(usize, usize),
}

fn models(n: usize) -> Vec<Vec<Producer>> {
    fn extend(n: usize, prefix: &mut Vec<Producer>, out: &mut Vec<Vec<Producer>>) {
        if prefix.len() == n {
            out.push(prefix.clone());
            return;
        }
        let available = prefix.len();
        let choices = [Producer::Argument(0), Producer::Argument(1)]
            .into_iter()
            .chain((0..available).map(Producer::Previous))
            .chain((0..available).flat_map(move |left| {
                (0..available).map(move |right| Producer::Pair(left, right))
            }));
        for next in choices {
            prefix.push(next);
            extend(n, prefix, out);
            prefix.pop();
        }
    }
    let mut out = Vec::new();
    extend(n, &mut Vec::new(), &mut out);
    out
}

fn number(order: &[usize], node: usize) -> usize {
    order
        .iter()
        .position(|&candidate| candidate == node)
        .unwrap()
}

fn oracle(nodes: &[Producer], roots: [usize; 2]) -> String {
    let mut values: Vec<Value> = Vec::with_capacity(nodes.len());
    for node in nodes {
        let value = match *node {
            Producer::Argument(port) => {
                operation('&', [Value::Parameter(port), Value::Literal(15)])
            }
            Producer::Previous(input) => operation('^', [values[input].clone(), Value::Literal(1)]),
            Producer::Pair(left, right) => {
                operation('^', [values[left].clone(), values[right].clone()])
            }
        };
        values.push(value);
    }
    format!("{:?},{:?}", values[roots[0]], values[roots[1]])
}

fn source(nodes: &[Producer], roots: [usize; 2], order: &[usize], raw: bool) -> String {
    let names: Vec<_> = (0..nodes.len())
        .map(|node| {
            if raw {
                ["r#type", "r#match", "r#loop"][node].to_owned()
            } else {
                format!("value{}", nodes.len() - node)
            }
        })
        .collect();
    let mut source = "fn compute(first: u32, second: u32) -> (u32, u32) {".to_owned();
    for &node in order {
        let expression = match nodes[node] {
            Producer::Argument(port) => {
                format!("{} & 15u32", ["first", "second"][port])
            }
            Producer::Previous(input) => format!("{} ^ 1u32", names[input]),
            Producer::Pair(left, right) => format!("{} ^ {}", names[left], names[right]),
        };
        write!(source, "let {} = {expression};", names[node]).unwrap();
    }
    write!(source, "({}, {}) }}", names[roots[0]], names[roots[1]]).unwrap();
    source
}

#[test]
fn all_small_legal_schedules_and_renamings_match_the_independent_graph_oracle() {
    let mut forms_by_graph = BTreeMap::<String, String>::new();
    let mut graphs_by_form = BTreeMap::<String, String>::new();
    for n in 1..=3 {
        let orders = permutations(n);
        for nodes in models(n) {
            for first in 0..n {
                for second in 0..n {
                    let roots = [first, second];
                    let graph = oracle(&nodes, roots);
                    for order in &orders {
                        if order.iter().any(|&node| match nodes[node] {
                            Producer::Previous(input) => {
                                number(order, input) >= number(order, node)
                            }
                            Producer::Pair(left, right) => {
                                number(order, left) >= number(order, node)
                                    || number(order, right) >= number(order, node)
                            }
                            Producer::Argument(_) => false,
                        }) {
                            continue;
                        }
                        for raw in [false, true] {
                            let source = source(&nodes, roots, order, raw);
                            let form = syn_canon::canonicalize(syn::parse_str(&source).unwrap())
                                .to_string();
                            if let Some(existing) = forms_by_graph.get(&graph) {
                                assert_eq!(existing, &form, "legal schedule {source}");
                            } else {
                                forms_by_graph.insert(graph.clone(), form.clone());
                            }
                            if let Some(existing) = graphs_by_form.get(&form) {
                                assert_eq!(existing, &graph, "distinct graph {source}");
                            } else {
                                graphs_by_form.insert(form, graph.clone());
                            }
                        }
                    }
                }
            }
        }
    }
}