All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aya.util.tyck.pat.ClassifierUtil Maven / Gradle / Ivy

There is a newer version: 0.36.0
Show newest version
// Copyright (c) 2020-2024 Tesla (Yinsen) Zhang.
// Use of this source code is governed by the MIT license that can be found in the LICENSE.md file.
package org.aya.util.tyck.pat;

import kala.collection.SeqView;
import kala.collection.immutable.ImmutableSeq;
import org.aya.util.Pair;
import org.aya.util.error.SourceNode;
import org.aya.util.error.SourcePos;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;

import java.util.function.Function;
import java.util.function.ObjIntConsumer;

public interface ClassifierUtil {
  Param subst(Subst subst, Param param);
  Pat normalize(Pat pat);
  Subst add(Subst subst, Term term);
  @ApiStatus.Internal @NotNull ImmutableSeq> classify1(
    @NotNull Subst subst, @NotNull Param param,
    @NotNull ImmutableSeq> clauses, int fuel
  );

  @ApiStatus.Internal default @NotNull ImmutableSeq>>
  classifyN(
    @NotNull Subst subst, @NotNull SeqView telescope,
    @NotNull ImmutableSeq>> clauses, int fuel
  ) {
    if (telescope.isEmpty()) return ImmutableSeq.of(new PatClass<>(
      ImmutableSeq.empty(), Indexed.indices(clauses)));
    var first = telescope.getFirst();
    var cls = classify1(subst, subst(subst, first),
      clauses.mapIndexed((ix, it) -> new Indexed<>(normalize(it.pat().getFirst()), ix)), fuel);
    return cls.flatMap(subclauses ->
      classifyN(add(subst, subclauses.term()),
        // Drop heads of both
        telescope.drop(1),
        subclauses.extract(clauses.map(it ->
          new Indexed<>(it.pat().drop(1), it.ix()))), fuel)
        .map(args -> args.map(ls -> ls.prepended(subclauses.term()))));
  }

  @ApiStatus.Internal default @NotNull ImmutableSeq>>
  classify2(
    @NotNull Subst subst, @NotNull Param tele1, @NotNull Function tele2,
    @NotNull ImmutableSeq>> clauses, int fuel
  ) {
    var cls = classify1(subst, subst(subst, tele1),
      clauses.mapIndexed((ix, it) -> new Indexed<>(normalize(it.pat().component1()), ix)), fuel);
    return cls.flatMap(subclauses ->
      classify1(add(subst, subclauses.term()),
        tele2.apply(subclauses.term()),
        subclauses.extract(clauses.map(it ->
          new Indexed<>(it.pat().component2(), it.ix()))), fuel)
        .map(args -> args.map(ls -> new Pair<>(subclauses.term(), ls))));
  }

  static int[] firstMatchDomination(
    @NotNull ImmutableSeq clauses,
    @NotNull ObjIntConsumer report, @NotNull ImmutableSeq> classes
  ) {
    // StackOverflow says they're initialized to zero
    var numbers = new int[clauses.size()];
    classes.forEach(results ->
      numbers[results.cls().min()]++);
    // ^ The minimum is not always the first one
    for (int i = 0; i < numbers.length; i++)
      if (0 == numbers[i]) report.accept(clauses.get(i).sourcePos(), i + 1);
    return numbers;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy