JS: Simple PROLOG interpreter

prolog.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Mini Prolog IDE (Tau Prolog)</title>
  <script src="https://cdn.jsdelivr.net/npm/tau-prolog@0.3.1/modules/core.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/tau-prolog@0.3.1/modules/lists.js"></script>
  <style>
    body {
      font-family: Arial, sans-serif;
      margin: 0;
      padding: 0;
      background: #f5f5f5;
    }
 
    .container {
      display: flex;
      height: 100vh;
    }
 
    .left, .right {
      padding: 20px;
      box-sizing: border-box;
    }
 
    .left {
      width: 50%;
      background: #ffffff;
      border-right: 1px solid #ccc;
    }
 
    .right {
      width: 50%;
      display: flex;
      flex-direction: column;
      gap: 20px;
    }
 
    .section {
      background: white;
      padding: 15px;
      border-radius: 8px;
      box-shadow: 0 2px 5px rgba(0,0,0,0.1);
      flex: 1;
      display: flex;
      flex-direction: column;
    }
 
    textarea {
      width: 100%;
      height: 100%;
      font-family: monospace;
      resize: none;
    }
 
    button {
      padding: 10px 20px;
      font-size: 16px;
      margin-top: 10px;
      align-self: flex-start;
    }
 
    #output {
      background: #eaeaea;
      padding: 10px;
      white-space: pre-wrap;
      overflow-y: auto;
      flex: 1;
    }
 
  </style>
</head>
<body>
<p> Wanna know how it's made? <a href="">wiki.ostrowski.net.pl</a></p>
  <div class="container">
    <div class="left section">
      <h2>Prolog Facts and Rules</h2>
      <textarea id="program" placeholder="e.g. parent(john, mary)."></textarea>
    </div>
 
    <div class="right">
      <div class="section">
        <h2>Query</h2>
        <textarea id="query" placeholder="e.g. parent(john, X)."></textarea>
        <button onclick="runQuery()">Run</button>
      </div>
      <div class="section">
        <h2>Results</h2>
        <div id="output"></div>
      </div>
    </div>
  </div>
 
  <script>
    pl.module("lists");
 
    function replacePolishChars(text) {
      const map = {
        'ą': 'a', 'ć': 'c', 'ę': 'e', 'ł': 'l',
        'ń': 'n', 'ó': 'o', 'ś': 's', 'ż': 'z', 'ź': 'z',
        'Ą': 'A', 'Ć': 'C', 'Ę': 'E', 'Ł': 'L',
        'Ń': 'N', 'Ó': 'O', 'Ś': 'S', 'Ż': 'Z', 'Ź': 'Z'
      };
      return text.replace(/[ąćęłńóśżźĄĆĘŁŃÓŚŻŹ]/g, c => map[c] || c);
    }
 
    function runQuery() {
      const rawProgram = document.getElementById("program").value;
      const rawQuery = document.getElementById("query").value;
      const outputDiv = document.getElementById("output");
 
      const program = replacePolishChars(rawProgram);
      const query = replacePolishChars(rawQuery);
 
      outputDiv.innerText = "Running...";
 
      const session = pl.create(1000);
      session.consult(program, {
        success: function () {
          session.query(query, {
            success: function () {
              let results = "";
              session.answers(answer => {
                if (answer === false) {
                  results += "No.\n";
                  outputDiv.innerText = results;
                } else if (pl.type.is_error(answer)) {
                  results += "Error: " + answer.args[0].id + "\n";
                  outputDiv.innerText = results;
                } else {
                  results += session.format_answer(answer) + "\n";
                  outputDiv.innerText = results;
                }
              });
            },
            error: function (err) {
              outputDiv.innerText = "Query error: " + err;
            }
          });
        },
        error: function (err) {
          outputDiv.innerText = "Program error: " + err;
        }
      });
    }
  </script>
 
</body>
</html>