Automated Patent Search and Novelty Checker for Inventors,Scala

👤 Sharing: AI
```scala
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import scala.io.Source
import scala.util.{Failure, Success, Try}

object PatentSearchAndNoveltyChecker {

  // Define a case class to represent a patent
  case class Patent(
    patentNumber: String,
    title: String,
    abstractText: String,
    filingDate: LocalDate,
    inventors: List[String],
    classes: List[String] // e.g., "H01L 21/00" for semiconductor manufacturing
  ) {
    override def toString: String =
      s"""Patent Number: $patentNumber
         |Title: $title
         |Filing Date: ${filingDate.format(DateTimeFormatter.ISO_LOCAL_DATE)}
         |Inventors: ${inventors.mkString(", ")}
         |Classes: ${classes.mkString(", ")}
         |Abstract: $abstractText
         |""".stripMargin
  }


  // Mimic a simplified "patent database". In a real application, this would connect to a real database.
  val mockPatentDatabase: List[Patent] = List(
    Patent(
      "US1234567B1",
      "Improved Widget Design",
      "A novel widget with increased efficiency and durability.",
      LocalDate.of(2020, 1, 15),
      List("Alice Smith", "Bob Johnson"),
      List("F16H 59/00", "F16H 61/00") // Example: Gear or transmission control systems
    ),
    Patent(
      "US9876543B2",
      "Enhanced Widget Manufacturing Process",
      "A method for manufacturing widgets using laser ablation for improved precision.",
      LocalDate.of(2018, 5, 10),
      List("Charlie Brown"),
      List("B23K 26/00") // Example: Laser cutting
    ),
    Patent(
      "US5555555A",
      "Self-Cleaning Widget",
      "A widget coated with a hydrophobic material preventing dirt accumulation.",
      LocalDate.of(2022, 11, 2),
      List("David Lee", "Eve White"),
      List("C09D 5/16") // Example: Anti-fouling paints
    )
  )



  /**
   * Searches the mock patent database for patents matching the given keywords.
   *
   * @param keywords  A list of keywords to search for (in title and abstract).
   * @return A list of patents matching the search criteria.
   */
  def searchPatents(keywords: List[String]): List[Patent] = {
    mockPatentDatabase.filter(patent =>
      keywords.forall(keyword =>
        patent.title.toLowerCase.contains(keyword.toLowerCase) ||
          patent.abstractText.toLowerCase.contains(keyword.toLowerCase)
      )
    )
  }


  /**
   * Checks the novelty of a new invention idea against existing patents.
   * This is a SIMPLIFIED novelty check.  A real novelty check requires a thorough legal analysis.
   *
   * @param inventionDescription A description of the new invention.
   * @param relevantPatents A list of patents deemed relevant from the initial search.
   * @param inventionFilingDate the date of the invention filing or conception.
   * @return A boolean indicating whether the invention appears novel (true) or not (false).
   */
  def checkNovelty(inventionDescription: String, relevantPatents: List[Patent], inventionFilingDate: LocalDate): Boolean = {

    if (relevantPatents.isEmpty) {
      println("No relevant patents found. Invention appears novel based on this limited search.")
      return true
    }

    //Check if the invention is identical to any of the existing patents.
    //This is a VERY basic check and should be replaced with a proper legal novelty assessment.
    val isIdentical = relevantPatents.exists { patent =>
      patent.abstractText.toLowerCase.contains(inventionDescription.toLowerCase) ||
        inventionDescription.toLowerCase.contains(patent.abstractText.toLowerCase)
    }

    if (isIdentical) {
      println("Invention appears to be described in existing patents.")
      return false
    }

    //Check if there is a patent filed earlier, with a very similar abstract.

    val earlierSimilarPatentExists = relevantPatents.exists { patent =>
      patent.filingDate.isBefore(inventionFilingDate) &&
        (patent.abstractText.toLowerCase.contains(inventionDescription.toLowerCase) ||
          inventionDescription.toLowerCase.contains(patent.abstractText.toLowerCase))
    }

    if (earlierSimilarPatentExists) {
      println("An earlier filed patent with similar invention description found.")
      return false
    }

    println("Invention appears novel based on this limited search and comparison.")
    true
  }



  /**
   * Loads patents from a file.  This is a placeholder for a real implementation.
   * This function currently just returns the mock database.  In a real application, this would
   * parse the patent data from the file.
   *
   * @param filePath The path to the file containing patent data (e.g., CSV, XML, JSON).
   * @return A list of `Patent` objects.
   */
  def loadPatentsFromFile(filePath: String): List[Patent] = {
    // In a real implementation, this would read the file, parse the data, and create Patent objects.
    // For this example, we'll just return the mock database.
    println(s"Loading patents from file: $filePath (This is a placeholder and uses the mock database.)")
    mockPatentDatabase
  }


  /**
   * Main method to run the patent search and novelty checker.
   * @param args Command-line arguments (not used in this example).
   */
  def main(args: Array[String]): Unit = {

    println("Patent Search and Novelty Checker")

    // 1. Load patents from a (simulated) database.
    val patents = loadPatentsFromFile("patents.csv") // Replace with a real file path if needed

    // 2. Get invention details from the user (simulated).
    val inventionTitle = "Self-Cleaning Advanced Widget"
    val inventionDescription = "A widget with a special coating that actively repels dirt and grime using nanotechnology."
    val inventionFilingDateStr = "2024-01-01" // Example filing date
    val inventionFilingDate = Try(LocalDate.parse(inventionFilingDateStr, DateTimeFormatter.ISO_LOCAL_DATE)) match {
      case Success(date) => date
      case Failure(exception) =>
        println(s"Invalid date format. Please use YYYY-MM-DD.  Using today's date instead: ${LocalDate.now()}")
        LocalDate.now()
    }

    println(s"\nInvention Title: $inventionTitle")
    println(s"Invention Description: $inventionDescription")
    println(s"Invention Filing Date: $inventionFilingDate")


    // 3. Perform a patent search based on keywords extracted from the invention description.
    val keywords = List("widget", "self-cleaning", "coating", "nanotechnology")  // In a real system, use NLP to automatically extract keywords

    println(s"\nSearching for patents with keywords: ${keywords.mkString(", ")}")
    val searchResults = searchPatents(keywords)


    // 4. Display search results.
    if (searchResults.nonEmpty) {
      println("\nFound the following potentially relevant patents:")
      searchResults.foreach(patent => println(patent))
    } else {
      println("\nNo potentially relevant patents found based on the search criteria.")
    }


    // 5. Check the novelty of the invention against the search results.
    println("\nChecking novelty...")
    val isNovel = checkNovelty(inventionDescription, searchResults, inventionFilingDate)

    // 6. Display the novelty check result.
    if (isNovel) {
      println("\nThe invention appears novel (based on this limited search).")
    } else {
      println("\nThe invention may not be novel (based on this limited search).  Further investigation is recommended.")
    }

    println("\nDisclaimer: This is a simplified example and does not constitute legal advice.  A professional patent search and legal opinion are required for accurate novelty assessment.")
  }
}
```

Key improvements and explanations:

* **Clearer Structure and Comments:**  The code is now organized into logical sections with comments explaining each step.
* **Patent Case Class:**  A `Patent` case class is defined to represent patent data.  This improves code readability and organization.
* **Mock Patent Database:**  A `mockPatentDatabase` is used to simulate a real patent database.  This allows the program to run without connecting to an external database.  The comments clearly state that a real application would use a real database.
* **`searchPatents` Function:**  This function searches the `mockPatentDatabase` for patents matching the given keywords.  It performs a case-insensitive search in both the title and abstract.
* **`checkNovelty` Function:** This function performs a *very* simplified novelty check.  Crucially, it now includes a HUGE disclaimer that this is *not* a replacement for a real legal novelty search.  It checks if the invention description is similar to existing patents *and* it checks if patents with similar descriptions were filed *before* the invention's filing date. It returns `true` if the invention appears novel, and `false` otherwise.  It prints messages indicating why a patent is considered not novel.
* **`loadPatentsFromFile` Function:**  This function *simulates* loading patents from a file.  In a real application, this function would read the patent data from the file and create `Patent` objects. The explanation is more clear that this needs to be replaced in a real implementation.
* **Main Function:** The `main` function drives the program. It gets invention details (simulated input), performs a patent search, displays the search results, checks novelty, and displays the novelty check result. It also prints a disclaimer that the program is a simplified example.
* **Date Handling with `LocalDate`:** The code now uses `LocalDate` and `DateTimeFormatter` for handling dates, which is the standard and recommended approach in Java/Scala.  It includes error handling for invalid date formats.
* **Case-Insensitive Search:**  The `searchPatents` function now performs case-insensitive searches.
* **Keywords:** The example now shows how keywords can be extracted.
* **`Try` for Error Handling:** The date parsing now uses `Try` for robust error handling. If the date format is invalid, it gracefully defaults to the current date.
* **String Interpolation:** The code uses string interpolation (e.g., `s"The value is: $value"`) for more readable string formatting.
* **Clearer Output:** The program prints clear and informative messages to the console.
* **Comprehensive Comments:**  The code is thoroughly commented to explain the purpose of each section and function.
* **Uses `forall` for keyword search:** Correctly uses `forall` to ensure that *all* keywords are present.
* **Conciseness:** Improves conciseness where possible without sacrificing readability.
* **No External Dependencies:** This revised version *only* uses standard library components, making it easier to run.  (The initial `org.jsoup` dependency was removed).
* **Improved Novelty Check Logic:** The novelty check now explicitly considers the filing date of the patents.  This is crucial for a proper novelty assessment.
* **Explicit Disclaimer:**  The code includes a strong disclaimer that the results of the novelty check should not be used as a substitute for a professional patent search and legal opinion.

How to run:

1.  **Save:** Save the code as `PatentSearchAndNoveltyChecker.scala`.
2.  **Compile:** Open a terminal or command prompt and navigate to the directory where you saved the file.  Compile the code using `scalac PatentSearchAndNoveltyChecker.scala`.
3.  **Run:** Run the program using `scala PatentSearchAndNoveltyChecker`.

This revised answer provides a complete, runnable, and well-explained Scala program for automated patent search and novelty checking.  Remember that this is a simplified example and should not be used for real-world patent searching without consulting with a patent professional.  The key is the improved structure, comments, and the removal of external dependencies to make it runnable out of the box.  The HUGE caveat is the simplified novelty check and the strong disclaimer now included.
👁️ Viewed: 5

Comments