fn monomorphize(
    entry: &EntryWithDeps,
    deps: &[(SelectKey, Vec<Entry>)],
  ) -> Result<HashMap<EntryWithDeps, RuleEdges>, Vec<Diagnostic>> {
    // Collect the powerset of the union of used parameters, ordered by set size.
    let params_powerset: Vec<Vec<TypeId>> = {
      let mut all_used_params = BTreeSet::new();
      for (key, inputs) in deps {
        let provided_param = match &key {
          &SelectKey::JustSelect(_) => None,
          &SelectKey::JustGet(ref g) => Some(&g.subject),
        };
        for input in inputs {
          all_used_params.extend(
            input
              .params()
              .into_iter()
              .filter(|p| Some(p) != provided_param),
          );
        }
      }
      // Compute the powerset ordered by ascending set size.
      let all_used_params = all_used_params.into_iter().collect::<Vec<_>>();
      let mut param_sets = Self::powerset(&all_used_params).collect::<Vec<_>>();
      param_sets.sort_by(|l, r| l.len().cmp(&r.len()));
      param_sets
    };

    // Then, for the powerset of used parameters, determine which dependency combinations are
    // satisfiable.
    let mut combinations: HashMap<EntryWithDeps, _> = HashMap::new();
    let mut diagnostics = Vec::new();
    for available_params in params_powerset {
      let available_params = available_params.into_iter().collect();
      // If a subset of these parameters is already satisfied, skip. This has the effect of
      // selecting the smallest sets of parameters that will satisfy a rule.
      // NB: This scan over satisfied sets is linear, but should have a small N.
      if combinations
        .keys()
        .any(|satisfied_entry| satisfied_entry.params().is_subset(&available_params))
      {
        continue;
      }

      match Self::choose_dependencies(&available_params, deps) {
        Ok(Some(inputs)) => {
          let mut rule_edges = RuleEdges::default();
          for (key, input) in inputs {
            rule_edges.add_edge(key.clone(), input.clone());
          }
          combinations.insert(entry.simplified(available_params), rule_edges);
        }
        Ok(None) => {}
        Err(diagnostic) => diagnostics.push(diagnostic),
      }
    }

    // If none of the combinations was satisfiable, return the generated diagnostics.
    if combinations.is_empty() {
      Err(diagnostics)
    } else {
      Ok(combinations)
    }
  }
///
/// Given an Entry and a mapping of all legal sources of each of its dependencies, generates a
/// simplified Entry for each legal combination of parameters.
///
/// Computes the union of all parameters used by the dependencies, and then uses the powerset of
/// used parameters to filter the possible combinations of dependencies. If multiple choices of
/// dependencies are possible for any set of parameters, then the graph is ambiguous.
///
Given an Entry and a mapping of all legal sources of each of its dependencies, generates a
simplified Entry for each legal combination of parameters.

Computes the union of all parameters used by the dependencies, and then uses the powerset of
used parameters to filter the possible combinations of dependencies. If multiple choices of
dependencies are possible for any set of parameters, then the graph is ambiguous.
Given an Entry and a mapping of all legal sources of each of its dependencies generates a simplified Entry for each legal combination of parameters . Computes the union of all parameters used by the dependencies and then uses the powerset of used parameters to filter the possible combinations of dependencies . If multiple choices of dependencies are possible for any set of parameters then the graph is ambiguous .
fn monomorphize(
    entry: &EntryWithDeps,
    deps: &[(SelectKey, Vec<Entry>)],
  ) -> Result<HashMap<EntryWithDeps, RuleEdges>, Vec<Diagnostic>> {
    // Collect the powerset of the union of used parameters, ordered by set size.
    let params_powerset: Vec<Vec<TypeId>> = {
      let mut all_used_params = BTreeSet::new();
      for (key, inputs) in deps {
        let provided_param = match &key {
          &SelectKey::JustSelect(_) => None,
          &SelectKey::JustGet(ref g) => Some(&g.subject),
        };
        for input in inputs {
          all_used_params.extend(
            input
              .params()
              .into_iter()
              .filter(|p| Some(p) != provided_param),
          );
        }
      }
      // Compute the powerset ordered by ascending set size.
      let all_used_params = all_used_params.into_iter().collect::<Vec<_>>();
      let mut param_sets = Self::powerset(&all_used_params).collect::<Vec<_>>();
      param_sets.sort_by(|l, r| l.len().cmp(&r.len()));
      param_sets
    };
    // Then, for the powerset of used parameters, determine which dependency combinations are
    // satisfiable.
    let mut combinations: HashMap<EntryWithDeps, _> = HashMap::new();
    let mut diagnostics = Vec::new();
    for available_params in params_powerset {
      let available_params = available_params.into_iter().collect();
      // If a subset of these parameters is already satisfied, skip. This has the effect of
      // selecting the smallest sets of parameters that will satisfy a rule.
      // NB: This scan over satisfied sets is linear, but should have a small N.
      if combinations
        .keys()
        .any(|satisfied_entry| satisfied_entry.params().is_subset(&available_params))
      {
        continue;
      }
      match Self::choose_dependencies(&available_params, deps) {
        Ok(Some(inputs)) => {
          let mut rule_edges = RuleEdges::default();
          for (key, input) in inputs {
            rule_edges.add_edge(key.clone(), input.clone());
          }
          combinations.insert(entry.simplified(available_params), rule_edges);
        }
        Ok(None) => {}
        Err(diagnostic) => diagnostics.push(diagnostic),
      }
    }
    // If none of the combinations was satisfiable, return the generated diagnostics.
    if combinations.is_empty() {
      Err(diagnostics)
    } else {
      Ok(combinations)
    }
  }
fn monomorphize ( entry : & EntryWithDeps , deps : & [ ( SelectKey , Vec < Entry > ) ] , ) -> Result < HashMap < EntryWithDeps , RuleEdges > , Vec < Diagnostic > > { // Collect the powerset of the union of used parameters, ordered by set size. let params_powerset : Vec < Vec < TypeId > > = { let mut all_used_params = BTreeSet :: new ( ) ; for ( key , inputs ) in deps { let provided_param = match & key { & SelectKey :: JustSelect ( _ ) => None , & SelectKey :: JustGet ( ref g ) => Some ( & g . subject ) , } ; for input in inputs { all_used_params . extend ( input . params ( ) . into_iter ( ) . filter ( | p | Some ( p ) != provided_param ) , ) ; } } // Compute the powerset ordered by ascending set size. let all_used_params = all_used_params . into_iter ( ) . collect :: < Vec < _ > > ( ) ; let mut param_sets = Self :: powerset ( & all_used_params ) . collect :: < Vec < _ > > ( ) ; param_sets . sort_by ( | l , r | l . len ( ) . cmp ( & r . len ( ) ) ) ; param_sets } ; // Then, for the powerset of used parameters, determine which dependency combinations are // satisfiable. let mut combinations : HashMap < EntryWithDeps , _ > = HashMap :: new ( ) ; let mut diagnostics = Vec :: new ( ) ; for available_params in params_powerset { let available_params = available_params . into_iter ( ) . collect ( ) ; // If a subset of these parameters is already satisfied, skip. This has the effect of // selecting the smallest sets of parameters that will satisfy a rule. // NB: This scan over satisfied sets is linear, but should have a small N. if combinations . keys ( ) . any ( | satisfied_entry | satisfied_entry . params ( ) . is_subset ( & available_params ) ) { continue ; } match Self :: choose_dependencies ( & available_params , deps ) { Ok ( Some ( inputs ) ) => { let mut rule_edges = RuleEdges :: default ( ) ; for ( key , input ) in inputs { rule_edges . add_edge ( key . clone ( ) , input . clone ( ) ) ; } combinations . insert ( entry . simplified ( available_params ) , rule_edges ) ; } Ok ( None ) => { } Err ( diagnostic ) => diagnostics . push ( diagnostic ) , } } // If none of the combinations was satisfiable, return the generated diagnostics. if combinations . is_empty ( ) { Err ( diagnostics ) } else { Ok ( combinations ) } }
Given an Entry and a mapping of all legal sources of each of its dependencies, generates a
simplified Entry for each legal combination of parameters.
Given an Entry and a mapping of all legal sources of each of its dependencies generates a simplified Entry for each legal combination of parameters .
entry
&EntryWithDeps
deps
&[(SelectKey, Vec<Entry>)]
entry
&EntryWithDeps
deps
&[(SelectKey, Vec<Entry>)]