SWI-Prolog - PHP - Html

Some days ago there has been a discussion about https, will try to understand better,
because serving html directly from swipl seems the better choice to me.

But meantime, I’ve worked out an approximately equivalent interface in PHP:

<?php

/*  File:    minigui/index.php
    Author:  Carlo
    Created: Sep 18 2020
    Purpose: help on https://swi-prolog.discourse.group/t/swi-prolog-php-html/2937
*/

/*  With swipl http dispatch support, we were able to handle
    http requests right inside the script, in php we must handle
    more low level details...
    Here is the (roughly) equivalent of predicate eval_formula/1.
    It's all about low level interface details, that we can ignore
    when running on swipl http server library...
*/

if ($f_encoded = ($_POST['formula'] ?? null)) {

  $formula = urldecode($f_encoded);
  
  // swipl will need the full path, so
  // assume quine.pl is in the same folder as this php script
  $quine = __DIR__ . '/quine.pl';
  $descp = [
    0 => ['pipe','r'],
    1 => ['pipe','w'],
    //2 => null
  ];
  $proc = proc_open("swipl -g quine -g halt $quine", $descp, $pipes);
  if (is_resource($proc)) {

    fwrite($pipes[0], $formula);
    fclose($pipes[0]);

    $Proof = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    $return_value = proc_close($proc);
    
    header('Content-type: application/json');
    echo json_encode(['proof'=>$Proof,'formula'=>'TBD']);
  }
  exit;
}

?>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Quine prover</title>
  </head>
  <div>
    <div>
      <label>
        <?=formulae_predef()?>
        Choose a formula or input your one
      </label>
    </div>
    <textarea id=formula rows=4 cols=60 title='enter your formula here, or select one predefined above'>
A
    </textarea>
    <div>
      <button id=eval_formula>eval</button>
      <pre id=proof_show>proof will show here</pre>
    </div>
  </div>
  <?=css()?>
  <?=js()?>
</html>
<?php

function formulae_predef() {
  ob_start();?>
  <select id=formulae_predef>
    <option>((P => Q) => P) -> P .</option>
    <option>((A <=> B) v C) & D .</option>
    <!-- add more, to illustrate accepted syntax -->
  </select>
  <?php return ob_get_clean();
}

function css() {
  ob_start();?>
<style>
</style>
  <?php return ob_get_clean();  
}

function js() {
  ob_start();?>
  <script>
window.onload = () => {

  const request = (url,formula) => fetch(url,{
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' },
    body: 'formula='+encodeURIComponent(formula)
  }).then(r => r.json())

  eval_formula.onclick = async (ev) => {
    let f = formula.value.trim()
    if (!f.endsWith('.')) f += '.'
    try {
      let result = await request("<?=$_SERVER['REQUEST_URI']?>", f)
      if (result.proof)
        proof_show.textContent = result.proof
      else
        proof_show.innerHTML = 'there was a problem:<b>'+JSON.stringify(result)+'<b>'
    } catch(e) {
      alert(e.message)
    }
  }
  formulae_predef.onchange = (ev) => {
    formula.value = ev.target.value
  }
}
  </script><?php
  return ob_get_clean();
}

This index.php should go into the Apache folder, maybe the path could be /var/www/html/minigui, together with quine.pl (or quineweb.pl, but then remember to correct the file name at line 23)

Then should be available at
https://www.vidal-rosset.net/minigui

1 Like