eyeprolog 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ hates(alice, nobody).
@@ -0,0 +1,20 @@
1
+ hates(alice, nobody).
2
+ why(
3
+ hates(alice, nobody),
4
+ proof(
5
+ goal(hates(alice, nobody)),
6
+ by(rule("snaf.pl", clause(3))),
7
+ bindings([binding("X", bob)]),
8
+ uses([
9
+ proof(
10
+ goal(person(bob)),
11
+ by(fact("snaf.pl", clause(2)))
12
+ ),
13
+ proof(
14
+ goal('\\+'(hates(alice, bob))),
15
+ by(builtin('\\+', 1))
16
+ )
17
+ ])
18
+ )
19
+ ).
20
+
@@ -0,0 +1,12 @@
1
+ % Alice loves Bob; Bob is a person. If Alice does not hate a person, conclude she hates Nobody.
2
+
3
+ %% goal: hates(alice, nobody)
4
+
5
+ % Facts
6
+ loves(alice, bob).
7
+ person(bob).
8
+
9
+ % Rule
10
+ hates(alice, nobody) :-
11
+ person(X),
12
+ \+ hates(alice, X).
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.1.3",
6
+ "version": "1.1.5",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
package/playground.html CHANGED
@@ -601,6 +601,7 @@
601
601
  "shoelace-polygon-area",
602
602
  "sieve",
603
603
  "skolem-functions",
604
+ "snaf",
604
605
  "socrates",
605
606
  "spacecraft-battery-diagnosis",
606
607
  "stable-marriage",
package/src/cli.js CHANGED
@@ -48,9 +48,9 @@ export async function main(argv) {
48
48
  options.version = true;
49
49
  } else if (!endOptions && (arg === '--warnings' || arg === '-w')) {
50
50
  options.warnings = true;
51
- } else if (!endOptions && arg === '--goal') {
51
+ } else if (!endOptions && (arg === '--goal' || arg === '-g')) {
52
52
  const goal = argv[++i];
53
- if (goal == null) throw new Error('option --goal requires a goal');
53
+ if (goal == null) throw new Error(`option ${arg} requires a goal`);
54
54
  options.goals.push(goal);
55
55
  } else if (!endOptions && arg.startsWith('-') && !arg.startsWith('--') && arg.length > 2) {
56
56
  const flags = arg.slice(1);
@@ -210,7 +210,7 @@ Options:
210
210
  -s, --stats Print solver statistics to stderr after execution.
211
211
  -v, --version Show the package version and exit.
212
212
  -w, --warnings Print non-fatal portability warnings to stderr.
213
- --goal goal Solve goal and print its ground answers; may be repeated.
213
+ -g, --goal goal Solve goal and print its ground answers; may be repeated.
214
214
  If omitted, use %% goal: comments from the inputs.
215
215
  -- Stop option parsing; following arguments are treated as files.
216
216
  `);
@@ -42,6 +42,7 @@ export const proofExamples = [
42
42
  'list-collection.pl',
43
43
  'proof-contrapositive.pl',
44
44
  'reusable-builtins.pl',
45
+ 'snaf.pl',
45
46
  'socrates.pl',
46
47
  'spacecraft-battery-diagnosis.pl',
47
48
  'term-tools.pl',
@@ -210,6 +210,7 @@ why(
210
210
  assertEqual(result.status, 0, 'exit status');
211
211
  assertIncludes(result.stdout, 'Usage:\n eyeprolog\n eyeprolog [options] [file-or-url.pl|- ...]', 'stdout');
212
212
  assertIncludes(result.stdout, 'With no arguments, start a Prolog REPL.', 'stdout');
213
+ assertIncludes(result.stdout, '-g, --goal goal', 'stdout');
213
214
  assertIncludes(result.stdout, '-p, --proof', 'stdout');
214
215
  assertIncludes(result.stdout, '-s, --stats', 'stdout');
215
216
  assertIncludes(result.stdout, '-v, --version', 'stdout');
@@ -366,6 +367,31 @@ why(
366
367
  assertEqual(result.stderr, '', 'stderr');
367
368
  },
368
369
  },
370
+ {
371
+ name: '-g supplies an explicit CLI goal',
372
+ run: () => {
373
+ const input = [
374
+ '%% goal: answer(metadata, X)',
375
+ 'value(metadata, ignored).',
376
+ 'value(explicit, selected).',
377
+ 'answer(Kind, Value) :- value(Kind, Value).',
378
+ '',
379
+ ].join('\n');
380
+ const result = runCli(['-g', 'answer(explicit, X)', '-'], { input });
381
+ assertEqual(result.status, 0, 'exit status');
382
+ assertEqual(result.stdout, 'answer(explicit, selected).\n', 'stdout');
383
+ assertEqual(result.stderr, '', 'stderr');
384
+ },
385
+ },
386
+ {
387
+ name: '-g requires a goal argument',
388
+ run: () => {
389
+ const result = runCli(['-g']);
390
+ assertEqual(result.status, 1, 'exit status');
391
+ assertEqual(result.stdout, '', 'stdout');
392
+ assertEqual(result.stderr, 'eyeprolog: option -g requires a goal\n', 'stderr');
393
+ },
394
+ },
369
395
 
370
396
  {
371
397
  name: '--proof enables query explanations',
@@ -6046,13 +6046,13 @@ displays command-line help.
6046
6046
  ### Selecting goals
6047
6047
 
6048
6048
  A Prolog source file states facts, rules, and ISO directives; the command line
6049
- selects what to solve. Supply `--goal` followed by a callable Prolog goal:
6049
+ selects what to solve. Supply `-g` or `--goal` followed by a callable Prolog goal:
6050
6050
 
6051
6051
  ```sh
6052
6052
  eyeprolog --goal 'ancestor(ada, Who)' examples/ancestor.pl
6053
6053
  ```
6054
6054
 
6055
- Repeat `--goal` to request several result relations in one run. EyeProlog prints
6055
+ Repeat `-g` or `--goal` to request several result relations in one run. EyeProlog prints
6056
6056
  their ground answers in the order the goals were supplied.
6057
6057
 
6058
6058
  For a self-running example, place the host goal in an ordinary comment:
@@ -6061,8 +6061,8 @@ For a self-running example, place the host goal in an ordinary comment:
6061
6061
  %% goal: ancestor(ada, Who)
6062
6062
  ```
6063
6063
 
6064
- When no `--goal` option is present, the CLI reads these comments from all input
6065
- sources and runs them in source order. An explicit `--goal` overrides them.
6064
+ When no `-g` or `--goal` option is present, the CLI reads these comments from all
6065
+ input sources and runs them in source order. An explicit goal option overrides them.
6066
6066
  Because `%% goal:` is a comment rather than a Prolog directive, another ISO
6067
6067
  processor may ignore it and the program remains portable Prolog text. External
6068
6068
  goals are still preferable when a script, shell history, or API call should
@@ -6075,7 +6075,7 @@ make the observed question explicit.
6075
6075
  | `-s`, `--stats` | Print solver counters to stderr |
6076
6076
  | `-v`, `--version` | Print the package version |
6077
6077
  | `-w`, `--warnings` | Print non-fatal portability warnings |
6078
- | `--goal Goal` | Solve a callable goal; may be repeated; overrides `%% goal:` comments |
6078
+ | `-g`, `--goal Goal` | Solve a callable goal; may be repeated; overrides `%% goal:` comments |
6079
6079
  | `--` | Treat following arguments as inputs |
6080
6080
 
6081
6081
  Short flags may be combined, so `-pw` is equivalent to `-p -w`.
@@ -6212,9 +6212,9 @@ Review questions:
6212
6212
  </figure>
6213
6213
 
6214
6214
  The [examples directory](https://github.com/eyereasoner/eyeprolog/tree/main/examples/) is the book's executable companion. The
6215
- top-level directory contains **189 self-contained runnable programs**. Every
6215
+ top-level directory contains **190 self-contained runnable programs**. Every
6216
6216
  source program has an exact answer file under
6217
- [examples/output](https://github.com/eyereasoner/eyeprolog/tree/main/examples/output/), and **60 selected programs** have a checked
6217
+ [examples/output](https://github.com/eyereasoner/eyeprolog/tree/main/examples/output/), and **61 selected programs** have a checked
6218
6218
  explanation under [examples/proof](https://github.com/eyereasoner/eyeprolog/tree/main/examples/proof/). The thematic tables below link every top-level program and open the program
6219
6219
  itself rather than merely naming it.
6220
6220
 
@@ -6297,6 +6297,7 @@ studies.
6297
6297
  | [Herbrand witnesses](https://github.com/eyereasoner/eyeprolog/blob/main/examples/herbrand-witnesses.pl) | Functional witness terms make existential structure and syntactic identity visible in both answers and derivations. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/herbrand-witnesses.pl) · [proof](https://github.com/eyereasoner/eyeprolog/blob/main/examples/proof/herbrand-witnesses.pl) |
6298
6298
  | [Reusable built-ins](https://github.com/eyereasoner/eyeprolog/blob/main/examples/reusable-builtins.pl) | Arithmetic, strings, lists, and term inspection compose through ordinary variables. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/reusable-builtins.pl) · [proof](https://github.com/eyereasoner/eyeprolog/blob/main/examples/proof/reusable-builtins.pl) |
6299
6299
  | [Skolem Functions](https://github.com/eyereasoner/eyeprolog/blob/main/examples/skolem-functions.pl) | Skolem functional terms in rule heads. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/skolem-functions.pl) |
6300
+ | [SNAF](https://github.com/eyereasoner/eyeprolog/blob/main/examples/snaf.pl) | Negation as failure establishes that Alice does not hate Bob before deriving that she hates Nobody. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/snaf.pl) · [proof](https://github.com/eyereasoner/eyeprolog/blob/main/examples/proof/snaf.pl) |
6300
6301
  | [Socrates](https://github.com/eyereasoner/eyeprolog/blob/main/examples/socrates.pl) | A fact and one rule turn the classical syllogism into a ground derivation. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/socrates.pl) · [proof](https://github.com/eyereasoner/eyeprolog/blob/main/examples/proof/socrates.pl) |
6301
6302
  | [UUID](https://github.com/eyereasoner/eyeprolog/blob/main/examples/uuid.pl) | `uuid/3` reproducibly creates one version 4 UUID atom from explicit random state; the example validates its canonical shape. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/uuid.pl) |
6302
6303
  | [Witch](https://github.com/eyereasoner/eyeprolog/blob/main/examples/witch.pl) | Burn the witch, adapted from Eyeling's examples/witch.n3. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/witch.pl) · [proof](https://github.com/eyereasoner/eyeprolog/blob/main/examples/proof/witch.pl) |