BUCKYVERSE

Specialized Content Detectors

Specialized detectors handle specific types of content that require different processing approaches, such as LaTeX commands, mathematical equations, and bibliographic references.

Core Implementation

defmodule Codexis.QualityChecker.SpecializedDetectors do
  @moduledoc """
  Specialized scanno detection for different content types
  """
  
  alias Codexis.LLM.OllamaClient
  
  def check_latex_commands(commands, model \\ "qwen3.0:8b") do
    prompt = """
    Check these LaTeX commands for OCR errors. Common issues:
    - Misspelled command names (\\sectiori → \\section)
    - Wrong brackets (\\cite(ref) → \\cite{ref})
    - Invalid command syntax
    
    Commands to check:
    #{Enum.map(commands, & &1.full) |> Enum.join("\n")}
    
    List any corrections needed.
    """
    
    OllamaClient.generate(prompt, model: model)
  end
  
  def check_math_content(math_blocks, model \\ "deepseek-r1:8b") do
    # Use DeepSeek-R1 for better mathematical reasoning
    math_blocks
    |> Enum.map(fn block ->
      check_single_math_block(block, model)
    end)
  end
  
  defp check_single_math_block(block, model) do
    prompt = """
    <anki_thinking>
    I need to check this mathematical expression for OCR errors. Common issues:
    - Greek letters confused with similar Latin letters
    - Subscripts/superscripts misplaced
    - Operators confused (− vs -, × vs x)
    - Parentheses/brackets mixed up
    - Mathematical symbols corrupted
    </anki_thinking>
    
    Check this LaTeX math for OCR errors:
    
    #{block.content}
    
    Look for:
    1. Malformed mathematical notation
    2. Inconsistent variable names
    3. Unbalanced delimiters
    4. Invalid LaTeX math syntax
    
    Provide corrections if needed.
    """
    
    OllamaClient.generate(prompt, model: model, temperature: 0.1)
  end
  
  def check_references(citations, model \\ "qwen3.0:8b") do
    prompt = """
    Check these bibliography citations for OCR errors:
    
    #{Enum.join(citations, "\n")}
    
    Common issues:
    - Year errors (2O23 → 2023)
    - Author name misspellings
    - Journal abbreviation errors
    
    List corrections needed.
    """
    
    OllamaClient.generate(prompt, model: model)
  end
end

Mathematical Content Detection

defmodule Codexis.QualityChecker.MathDetector do
  @moduledoc """
  Specialized detection for mathematical content
  """
  
  alias Codexis.LLM.OllamaClient
  
  @math_correction_schema %{
    corrections: %{
      type: "array",
      items: %{
        type: "object",
        properties: %{
          original: %{type: "string"},
          corrected: %{type: "string"},
          type: %{type: "string", enum: ["symbol", "operator", "delimiter", "script"]},
          reason: %{type: "string"},
          confidence: %{type: "number"},
          position: %{type: "integer"}
        }
      }
    }
  }
  
  def check_equation(equation_content, opts \\ []) do
    model = Keyword.get(opts, :model, "deepseek-r1:8b")
    
    prompt = build_math_prompt(equation_content)
    
    case OllamaClient.generate_structured(prompt, @math_correction_schema, model: model) do
      {:ok, result} -> process_math_corrections(result)
      {:error, reason} -> {:error, reason}
    end
  end
  
  defp build_math_prompt(content) do
    """
    Analyze this LaTeX mathematical expression for OCR errors:
    
    #{content}
    
    Focus on:
    1. Greek letter substitutions (α→a, β→b, θ→0)
    2. Operator errors (∑→Σ, ∫→f, ·→.)
    3. Delimiter matching (mismatched brackets/parentheses)
    4. Subscript/superscript placement
    5. Common math symbol corruptions
    
    For each error, identify:
    - The original incorrect symbol/text
    - The corrected version
    - The type of error (symbol, operator, delimiter, script)
    - Why it's likely an error
    - Confidence level (0-1)
    - Character position
    """
  end
  
  defp process_math_corrections(result) do
    result["corrections"]
    |> Enum.map(fn correction ->
      # Add additional validation for math corrections
      if valid_math_correction?(correction) do
        correction
      else
        Map.put(correction, "confidence", correction["confidence"] * 0.7)
      end
    end)
  end
  
  defp valid_math_correction?(correction) do
    # Basic validation for mathematical corrections
    case correction["type"] do
      "symbol" -> valid_symbol_correction?(correction)
      "operator" -> valid_operator_correction?(correction)
      "delimiter" -> valid_delimiter_correction?(correction)
      "script" -> valid_script_correction?(correction)
      _ -> true
    end
  end
  
  defp valid_symbol_correction?(correction) do
    # Check if the correction involves valid mathematical symbols
    valid_symbols = ~w(alpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu nu xi omicron pi rho sigma tau upsilon phi chi psi omega)
    
    orig = String.downcase(correction["original"])
    corr = String.downcase(correction["corrected"])
    
    Enum.any?(valid_symbols, fn symbol ->
      String.contains?(corr, symbol) || String.contains?(orig, symbol)
    end)
  end
  
  defp valid_operator_correction?(_correction), do: true
  defp valid_delimiter_correction?(_correction), do: true
  defp valid_script_correction?(_correction), do: true
end

LaTeX Command Validation

defmodule Codexis.QualityChecker.CommandValidator do
  @moduledoc """
  Validates and corrects LaTeX commands
  """
  
  alias Codexis.LLM.OllamaClient
  
  @common_commands ~w(
    section subsection subsubsection paragraph
    chapter part appendix
    begin end
    cite citep citet ref label
    includegraphics caption
    textbf textit emph
    frac sqrt sum prod int
    alpha beta gamma delta
    usepackage documentclass
  )
  
  def validate_commands(commands, model \\ "qwen3.0:8b") do
    # First pass: check against known commands
    known_corrections = check_known_commands(commands)
    
    # Second pass: use LLM for uncertain cases
    uncertain_commands = filter_uncertain_commands(commands, known_corrections)
    
    if Enum.empty?(uncertain_commands) do
      known_corrections
    else
      llm_corrections = check_with_llm(uncertain_commands, model)
      merge_corrections(known_corrections, llm_corrections)
    end
  end
  
  defp check_known_commands(commands) do
    commands
    |> Enum.map(fn command ->
      if correction = find_known_correction(command.command) do
        %{
          original: command.full,
          corrected: String.replace(command.full, command.command, correction),
          reason: "Common LaTeX command misspelling",
          confidence: 0.95,
          type: :command
        }
      else
        nil
      end
    end)
    |> Enum.filter(& &1)
  end
  
  defp find_known_correction(command) do
    command_lower = String.downcase(command)
    
    # Find the closest matching command
    @common_commands
    |> Enum.map(fn known ->
      {known, String.jaro_distance(command_lower, known)}
    end)
    |> Enum.filter(fn {_, distance} -> distance > 0.8 end)
    |> Enum.max_by(fn {_, distance} -> distance end, fn -> nil end)
    |> case do
      nil -> nil
      {correct_command, _} -> correct_command
    end
  end
  
  defp filter_uncertain_commands(commands, known_corrections) do
    corrected_commands = Enum.map(known_corrections, & &1.original)
    
    Enum.filter(commands, fn command ->
      not Enum.member?(corrected_commands, command.full)
    end)
  end
  
  defp check_with_llm(commands, model) do
    prompt = """
    Check these LaTeX commands for OCR errors:
    
    #{Enum.map(commands, & &1.full) |> Enum.join("\n")}
    
    Common issues:
    - Misspelled command names
    - Wrong delimiters (parentheses instead of braces)
    - Invalid syntax
    
    For each error, provide the corrected command.
    """
    
    case OllamaClient.generate(prompt, model: model) do
      {:ok, response} -> parse_llm_corrections(response, commands)
      {:error, _} -> []
    end
  end
  
  defp parse_llm_corrections(response, _commands) do
    # Parse the LLM response to extract corrections
    # This is a simplified version - real implementation would be more robust
    []
  end
  
  defp merge_corrections(known, llm) do
    known ++ llm
  end
end

Bibliography and Citation Detection

defmodule Codexis.QualityChecker.BibliographyDetector do
  @moduledoc """
  Detects OCR errors in bibliographic content
  """
  
  alias Codexis.LLM.OllamaClient
  
  def check_bibliography_entry(entry, model \\ "qwen3.0:8b") do
    prompt = """
    Check this bibliography entry for OCR errors:
    
    #{entry}
    
    Common issues:
    1. Author names with character substitutions
    2. Year errors (O instead of 0, l instead of 1)
    3. Journal name corruptions
    4. DOI/URL errors
    5. Page number issues
    
    Provide corrections for any errors found.
    """
    
    OllamaClient.generate(prompt, model: model)
  end
  
  def check_citation_consistency(citations, bibliography, model \\ "qwen3.0:8b") do
    prompt = """
    Check citation consistency between these citations and bibliography entries:
    
    Citations found in text:
    #{Enum.join(citations, "\n")}
    
    Bibliography entries:
    #{Enum.join(bibliography, "\n")}
    
    Look for:
    1. Citations without matching bibliography entries
    2. Bibliography entries that are never cited
    3. Inconsistent citation keys (possible OCR errors)
    
    Report any inconsistencies or errors.
    """
    
    OllamaClient.generate(prompt, model: model)
  end
  
  def validate_dois(dois, model \\ "qwen3.0:8b") do
    prompt = """
    Check these DOIs for OCR errors:
    
    #{Enum.join(dois, "\n")}
    
    DOI format should be: 10.xxxx/yyyy
    
    Common OCR errors in DOIs:
    - O/0 confusion
    - l/1 confusion
    - Missing or extra dots/slashes
    
    Correct any malformed DOIs.
    """
    
    OllamaClient.generate(prompt, model: model)
  end
end

Code Block Detection

defmodule Codexis.QualityChecker.CodeDetector do
  @moduledoc """
  Detects OCR errors in code blocks and listings
  """
  
  alias Codexis.LLM.OllamaClient
  
  def check_code_block(code, language, model \\ "qwen3.0:8b") do
    prompt = """
    Check this #{language} code block for OCR errors:
    
    ```#{language}
    #{code}
    ```
    
    Common OCR errors in code:
    1. Similar character confusion (0/O, 1/l, etc.)
    2. Bracket/parenthesis errors
    3. Operator errors (==/>-, !=/>)
    4. Keyword misspellings
    5. Indentation issues
    
    Provide corrections for any errors that would prevent compilation/execution.
    """
    
    case OllamaClient.generate(prompt, model: model) do
      {:ok, response} -> parse_code_corrections(response)
      {:error, reason} -> {:error, reason}
    end
  end
  
  defp parse_code_corrections(response) do
    # Extract and parse code corrections from LLM response
    %{
      corrections: [],
      fixed_code: response
    }
  end
  
  def validate_syntax(code, language) do
    # Language-specific syntax validation
    case language do
      "python" -> validate_python_syntax(code)
      "elixir" -> validate_elixir_syntax(code)
      "latex" -> validate_latex_syntax(code)
      _ -> {:ok, :unknown_language}
    end
  end
  
  defp validate_python_syntax(code) do
    # Basic Python syntax validation
    {:ok, :valid}
  end
  
  defp validate_elixir_syntax(code) do
    # Use Code.string_to_quoted for validation
    case Code.string_to_quoted(code) do
      {:ok, _} -> {:ok, :valid}
      {:error, {line, error, _}} -> {:error, "Line #{line}: #{error}"}
    end
  end
  
  defp validate_latex_syntax(code) do
    # Basic LaTeX syntax validation
    {:ok, :valid}
  end
end