<commit_before>defmodule Core.Fact do
  @moduledoc """
  A Fact is a collection of annotations that answers a question.

  ## Fields

  Field         | Type           |
  :------------ | :------------- | :---------------------
  `question`    | `belongs_to`   | `Core.Question`
  `annotations` | `many_to_many` | `Core.Tag` through `Core.AnnotationTag`
  """
  use Core.Web, :model

  schema "facts" do
    belongs_to :question, Core.Question
    many_to_many :fact_annotations, Core.Annotation, join_through: Core.FactAnnotation

    field :annotations, {:array, :integer}, virtual: true

    timestamps()
  end

  @doc """
  Builds a changeset based on the `struct` and `params`.

  ## Parameters

  Required parameters: `question_id`.
  """
  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:question_id, :annotations])
    |> validate_required([:question_id, :annotations])
    |> foreign_key_constraint(:question_id)
  end
end<commit_msg>Implements Fact.answers?/2 to check if a Fact answers a Question<commit_after>defmodule Core.Fact do
  @moduledoc """
  A Fact is a collection of annotations that answers a question.

  ## Fields

  Field         | Type           |
  :------------ | :------------- | :---------------------
  `question`    | `belongs_to`   | `Core.Question`
  `annotations` | `many_to_many` | `Core.Tag` through `Core.AnnotationTag`
  """
  use Core.Web, :model

  schema "facts" do
    belongs_to :question, Core.Question
    many_to_many :fact_annotations, Core.Annotation, join_through: Core.FactAnnotation

    field :annotations, {:array, :integer}, virtual: true

    timestamps()
  end

  @doc """
  Builds a changeset based on the `struct` and `params`.

  ## Parameters

  Required parameters: `question_id`.
  """
  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:question_id, :annotations])
    |> validate_required([:question_id, :annotations])
    |> foreign_key_constraint(:question_id)
  end

  @doc """
  Check if a fact answers a question completely
  """
  def answers?(fact, question) do
    available = fact.annotations
    |> Enum.map(fn annotation -> annotation.tags end)
    |> List.flatten()

    question.answer
    |> Enum.filter(fn tag -> tag.required end)
    |> Enum.map(fn item -> item.tag.id end)
    |> Enum.all?(&Enum.member?(available, &1))
  end
end
{'fraction_non_alphanumeric': 0.16362865621025857, 'fraction_numerical': 0.000847816871555744, 'mean_word_length': 2.8187702265372168, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4763006', 'n_tokens_mistral': 748, 'n_tokens_neox': 699, 'n_words': 190}