├── README.md
├── bin
├── YPShell.exe
├── YPShell.py
├── YieldProlog.js
└── queryEditor.html
├── doc
├── YieldProlog.js
├── benchmarks.html
├── index.html
├── queryEditor.html
├── tutorial1.html
├── tutorial2.html
├── tutorial3.html
├── tutorial4.html
└── tutorial_toc.html
└── source
├── csharp
├── Atom.cs
├── BagofAnswers.cs
├── Compiler.cs
├── FindallAnswers.cs
├── Functor.cs
├── Functor1.cs
├── Functor2.cs
├── Functor3.cs
├── IndexedAnswers.cs
├── ListPair.cs
├── Parser.cs
├── PrologException.cs
├── Variable.cs
├── YP.cs
├── examples
│ ├── Benchmarks
│ │ ├── IsoTestSuite.cs
│ │ ├── NaiveQueens.cs
│ │ ├── Queens.cs
│ │ ├── YieldPrologBenchmarks.csproj
│ │ ├── YieldPrologBenchmarks.csproj.user
│ │ ├── YieldPrologBenchmarks.sln
│ │ ├── YieldPrologBenchmarks.suo
│ │ └── monomake.bat
│ ├── YPShell
│ │ ├── YPShell.cs
│ │ ├── YPShell.csproj
│ │ ├── YPShell.csproj.user
│ │ ├── YPShell.sln
│ │ ├── YPShell.suo
│ │ └── monomake.bat
│ └── YieldPrologTutorial
│ │ ├── Tutorial1.cs
│ │ ├── Tutorial2.cs
│ │ ├── Tutorial3.cs
│ │ ├── Tutorial4.cs
│ │ ├── YieldPrologTutorial.csproj
│ │ ├── YieldPrologTutorial.csproj.user
│ │ ├── YieldPrologTutorial.sln
│ │ ├── YieldPrologTutorial.suo
│ │ └── monomake.bat
└── update.bat
├── javascript
├── Atom.js
├── BagofAnswers.js
├── Compiler.js
├── FindallAnswers.js
├── Functor.js
├── Functor1.js
├── Functor2.js
├── Functor3.js
├── IndexedAnswers.js
├── ListPair.js
├── Parser.js
├── PrologException.js
├── Variable.js
├── YP.js
├── YieldProlog.js
├── endComment.js
├── examples
│ ├── Benchmarks
│ │ ├── isoTestSuite.html
│ │ ├── isoTestSuite.js
│ │ ├── naiveQueens.html
│ │ ├── naiveQueens.js
│ │ ├── queens.html
│ │ └── queens.js
│ └── YieldPrologTutorial
│ │ ├── tutorial1.html
│ │ ├── tutorial1.js
│ │ ├── tutorial2.html
│ │ ├── tutorial2.js
│ │ ├── tutorial3.html
│ │ ├── tutorial3.js
│ │ ├── tutorial4.html
│ │ └── tutorial4.js
├── makeYieldProlog.bat
└── readme.js
├── prolog
├── compiler.P
├── isoTestSuite.P
└── parser.P
└── python
├── Atom.py
├── BagofAnswers.py
├── Compiler.py
├── FindallAnswers.py
├── Functor.py
├── Functor1.py
├── Functor2.py
├── Functor3.py
├── IndexedAnswers.py
├── ListPair.py
├── Parser.py
├── PrologException.py
├── Variable.py
├── YP.py
└── examples
├── Benchmarks
├── isoTestSuite.py
├── naiveQueens.py
└── queens.py
└── YieldPrologTutorial
├── tutorial1.py
├── tutorial2.py
├── tutorial3.py
└── tutorial4.py
/README.md:
--------------------------------------------------------------------------------
1 | Yield Prolog
2 | ============
3 |
4 | Welcome to Yield Prolog. This fork is based on the original YieldProlog project available here:
5 | http://yieldprolog.sourceforge.net/
6 |
7 | Contents
8 | --------
9 |
10 | - **bin** contains executables, including:
11 | - YPShell.exe - Yield Prolog for C# interactive shell for Windows.
12 | - queryEditor.html - Yield Prolog browser shell for Javascript.
13 | - YPShell.py - Yield Prolog for Python interactive shell.
14 |
15 | - **doc** contains a snapshot of the Yield Prolog web site including the tutorial.
16 | Open index.html in your browser.
17 |
18 | - **source** contains a folder for the source of each supported platform.
19 | The examples subfolder for each platform contains the YPShell, tutorial examples and benchmarks code.
20 |
21 | Make
22 | ----
23 |
24 | Here are instructions to make and run Tutorial1 on various platforms.
25 | You can do something similar to make the other tutorials, the benchmarks,
26 | or your own Yield Prolog program.
27 |
28 | To make Tutorial1 under Visual C# 2008:
29 | - Open source\csharp\examples\YieldPrologTutorial\YieldPrologTutorial.sln
30 | - Make sure the Startup Object is set correctly, e.g. to Tutorial1
31 | - Press F5 to build and run
32 |
33 | To make Tutorial1 under Mono 1.9.1 in Windows:
34 | - On the Start menu, run Programs/Mono 1.9.1 for Windows/Mono-1.9.1 Command Prompt
35 | - Use cd to change directory to source\csharp\examples\YieldPrologTutorial
36 | - Enter: monomake Tutorial1.cs
37 | - Run Tutorial1.exe
38 |
39 | To make Tutorial1 under Python 2.6 for Windows:
40 | - On the Start menu, run Programs/Python 2.5/IDLE (Python GUI)
41 | - Select the menu File/Open and open source\python\examples\YieldPrologTutorial\tutorial1.py
42 | - Press F5 to run the module
43 |
--------------------------------------------------------------------------------
/bin/YPShell.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vslab/YieldProlog/11f68cd05d55a8b56681b1c7572b9067e7816915/bin/YPShell.exe
--------------------------------------------------------------------------------
/bin/YPShell.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import sys
30 | # Hack sys.path for imports.
31 | sys.path.append("../source/python")
32 | from YP import *
33 | from Atom import *
34 | from Compiler import *
35 | from ListPair import *
36 | from Variable import *
37 |
38 | def main():
39 | print "Yield Prolog Shell. Enter ctrl-D to exit."
40 |
41 | while True:
42 | print "?- ",
43 | goalString = sys.stdin.readline()
44 | if goalString == "":
45 | break
46 | if goalString == "\n":
47 | print "Enter ctrl-D to exit."
48 | continue
49 |
50 | Goal = Variable()
51 | VariableList = Variable()
52 | for l1 in parseGoal(goalString, Goal, VariableList):
53 | try:
54 | gotMatch = False
55 | for l2 in YP.getIterator(Goal, None):
56 | gotMatch = True
57 | if YP.getValue(VariableList) != Atom.NIL:
58 | # We are showing values, so allow the user to enter ";" to display the next match.
59 | writeValues(VariableList)
60 | continuePrompt = sys.stdin.readline()
61 | if len(continuePrompt) > 0 and continuePrompt[0] != ';':
62 | break
63 |
64 | if gotMatch:
65 | if YP.getValue(VariableList) == Atom.NIL:
66 | # We didn't show any values. So just write true after matching (one or more times).
67 | print "true"
68 | else:
69 | print
70 | else:
71 | print "fail"
72 | except PrologException as exception:
73 | print str(exception._term)
74 |
75 | # Parse goalString and yield for each Goal, setting VariableList to a list of
76 | # (variableAtom = Var).
77 | def parseGoal(goalString, Goal, VariableList):
78 | # The parser requires a newline at the end.
79 | YP.see(YP.StringReader(goalString + '\n'))
80 | TermList = Variable()
81 | # parseInput sets TermList to a list of f(Goal, VariableList).
82 | for l1 in parseInput(TermList):
83 | # Close the input now before yielding.
84 | YP.seen()
85 | # Iterate through each member of TermList.
86 | TermList = YP.getValue(TermList)
87 | while isinstance(TermList, Functor2) and TermList._name == Atom.DOT:
88 | # Unify the head of the list with f(Goal, VariableList).
89 | for l2 in YP.unify(TermList._arg1, Functor2(Atom.F, Goal, VariableList)):
90 | yield False
91 | TermList = YP.getValue(TermList._arg2)
92 | return
93 |
94 | # Close the input in case parseInput failed.
95 | YP.seen()
96 |
97 | # Write out each entry in VariableList which is a list of (variableAtom = Var)
98 | def writeValues(VariableList):
99 | VariableList = YP.getValue(VariableList)
100 | while isinstance(VariableList, Functor2) and VariableList._name == Atom.DOT:
101 | variableAndValue = YP.getValue(VariableList._arg1)
102 | if isinstance(variableAndValue, Functor2):
103 | print
104 | print YP.getValue(variableAndValue._arg1), "=", YP.getValue(variableAndValue._arg2),
105 | VariableList = YP.getValue(VariableList._arg2)
106 |
107 | main()
108 |
109 |
110 |
--------------------------------------------------------------------------------
/bin/queryEditor.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
89 | Yield Prolog Query Editor
90 |
91 |
92 |
94 |
95 |
96 | ^^Home
98 |
99 |
100 | Yield Prolog Query Editor
101 |
102 |
103 |
104 |
105 |
106 | Congratulations! Your browser
107 | has just loaded the full-featured Prolog environment in YieldProlog.js , complete with a
109 | Prolog parser and compiler.
110 | Click one of the Samples or type some Prolog, then
111 | click Run to see the result. (Requires Firefox 3 or Seamonkey
114 | 2 .)
115 |
116 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/doc/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 | Yield Prolog
7 |
8 |
9 |
11 |
12 |
13 |
15 | Yield Prolog
16 | Download
17 |
18 | Documentation
20 |
21 | Query Editor
22 |
23 | Benchmarks
24 |
25 | Report
27 | Bugs
28 |
29 | Sourceforge
30 | Project
31 |
32 |
35 |
36 | Yield
37 | Prolog lets you embed
38 | Prolog programs directly in Python, C# [1]
39 | or Javascript [2]
40 | by using the yield
41 | keyword. For example,
42 | here is the classic "uncle" predicate in Prolog:
43 |
44 |
46 |
47 |
48 |
49 | uncle(Person, Uncle) :- parent(Person, Parent), brother(Parent, Uncle).
50 |
51 |
52 |
53 |
54 |
55 | (This says that a person has an uncle if the person has a parent and
56 | that
57 | parent has a brother.) And here it is in Yield Prolog:
58 |
59 |
61 |
62 |
63 | Python
65 |
66 | C#
68 |
69 |
70 |
71 |
72 | def uncle(Person, Uncle): Parent = Variable() for l1 in parent(Person, Parent): for l2 in brother(Parent, Uncle): yield False
73 |
74 |
75 | IEnumerable<bool> uncle(object Person, object Uncle) { Variable Parent = new Variable(); foreach (bool l1 in parent(Person, Parent)) { foreach (bool l2 in brother(Parent, Uncle)) yield return false; } }
76 |
77 |
78 |
79 | Javascript
80 |
81 |
82 |
83 | function uncle(Person, Uncle) { var Parent = new Variable(); for each (var l1 in parent(Person, Parent)) { for each (var l2 in brother(Parent, Uncle)) yield false; } }
84 |
85 |
86 |
87 |
88 |
89 | As you can see, the flow of the code in Yield Prolog is similar to
90 | Prolog. The Tutorial explains how
91 | these
92 | examples work, without expecting you to know Prolog. And the benchmarks show that Yield Prolog in C# can
94 | be faster than efficient Prolog systems like Yap Prolog and XSB.
95 |
96 | Yield Prolog is made possible by the yield keyword, which
98 | automatically creates iterators that you can nest, combined with Yield
99 | Prolog's Variable class
100 | which can unify a variable with other values (just like in
101 | Prolog). There is no "API" standing between your code and Yield Prolog,
102 | because
103 | you just use the yield
104 | keyword to make "iterator functions" wherever you need them. Yield
105 | Prolog is part of your code, which can mix Prolog-style predicates
106 | directly with ordinary arrays, file I/O, GUI calls and all your own
107 | classes. Because it lets you mix these, Yield Prolog unifies the declarative
109 | and procedural
110 | programming models.
111 |
112 | 1.
113 | Tested
114 | with
115 | C#
116 | .NET 2008 and Mono 2.0.
117 | 2.
119 | Yield Prolog for Javascript is supported in Firefox 3 and Seamonkey 2 ,
122 | which fully supports the yield
123 | keyword in EcmaScript 3.1.
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/doc/tutorial_toc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 | Yield Prolog Documentation
7 |
8 |
9 |
23 | For the change log of each release, see the Yield Prolog News .
25 | Tutorial Table of Contents
26 |
27 | Introduction
28 |
51 | Variable
52 | and "Cut"
53 |
61 | ListPair
62 |
68 | Compiler
69 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/source/csharp/FindallAnswers.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | using System;
32 | using System.Collections;
33 | using System.Collections.Generic;
34 |
35 | namespace YieldProlog
36 | {
37 | ///
38 | /// A FindallAnswers holds answers for findall.
39 | ///
40 | public class FindallAnswers
41 | {
42 | private object _template;
43 | private List _bagArray;
44 |
45 | public FindallAnswers(object Template)
46 | {
47 | _template = Template;
48 | _bagArray = new List();
49 | }
50 |
51 | public void add()
52 | {
53 | _bagArray.Add(YP.makeCopy(_template, new Variable.CopyStore()));
54 | }
55 |
56 | public List resultArray()
57 | {
58 | return _bagArray;
59 | }
60 |
61 | ///
62 | /// Unify Bag with the result. This frees the internal answers, so you can only call this once.
63 | ///
64 | ///
65 | ///
66 | public IEnumerable result(object Bag)
67 | {
68 | object result = ListPair.make(_bagArray);
69 | // Try to free the memory.
70 | _bagArray = null;
71 | return YP.unify(Bag, result);
72 | }
73 |
74 | ///
75 | /// This is a simplified findall when the goal is a single call.
76 | ///
77 | ///
78 | ///
79 | ///
80 | ///
81 | public static IEnumerable findall(object Template, IEnumerable goal, object Bag)
82 | {
83 | FindallAnswers findallAnswers = new FindallAnswers(Template);
84 | foreach (bool l1 in goal)
85 | findallAnswers.add();
86 | return findallAnswers.result(Bag);
87 | }
88 |
89 | ///
90 | /// Like findall, except return an array of the results.
91 | ///
92 | ///
93 | ///
94 | ///
95 | public static List findallArray(object Template, IEnumerable goal)
96 | {
97 | FindallAnswers findallAnswers = new FindallAnswers(Template);
98 | foreach (bool l1 in goal)
99 | findallAnswers.add();
100 | return findallAnswers.resultArray();
101 | }
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/source/csharp/Functor1.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | using System;
32 | using System.Collections.Generic;
33 |
34 | namespace YieldProlog
35 | {
36 | public class Functor1 : IUnifiable
37 | {
38 | public readonly Atom _name;
39 | public readonly object _arg1;
40 |
41 | public Functor1(Atom name, object arg1)
42 | {
43 | _name = name;
44 | _arg1 = arg1;
45 | }
46 |
47 | public Functor1(string name, object arg1)
48 | : this(Atom.a(name), arg1)
49 | {
50 | }
51 |
52 | ///
53 | /// If arg is another Functor1, then succeed (yield once) if this and arg have the
54 | /// same name and the functor args unify, otherwise fail (don't yield).
55 | /// If arg is a Variable, then call its unify to unify with this.
56 | /// Otherwise fail (don't yield).
57 | ///
58 | ///
59 | ///
60 | public IEnumerable unify(object arg)
61 | {
62 | arg = YP.getValue(arg);
63 | if (arg is Functor1)
64 | {
65 | Functor1 argFunctor = (Functor1)arg;
66 | if (_name.Equals(argFunctor._name))
67 | {
68 | foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1))
69 | yield return false;
70 | }
71 | }
72 | else if (arg is Variable)
73 | {
74 | foreach (bool l1 in ((Variable)arg).unify(this))
75 | yield return false;
76 | }
77 | }
78 |
79 | public override string ToString()
80 | {
81 | return _name + "(" + YP.getValue(_arg1) + ")";
82 | }
83 |
84 | public bool termEqual(object term)
85 | {
86 | term = YP.getValue(term);
87 | if (term is Functor1)
88 | {
89 | Functor1 termFunctor = (Functor1)term;
90 | return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1);
91 | }
92 | return false;
93 | }
94 |
95 | public override int GetHashCode()
96 | {
97 | return _name.GetHashCode() ^ YP.getValue(_arg1).GetHashCode();
98 | }
99 |
100 | public bool lessThan(Functor1 functor)
101 | {
102 | // Do the equal check first since it is faster.
103 | if (!_name.Equals(functor._name))
104 | return _name.lessThan(functor._name);
105 |
106 | return YP.termLessThan(_arg1, functor._arg1);
107 | }
108 |
109 | public bool ground()
110 | {
111 | return YP.ground(_arg1);
112 | }
113 |
114 | public void addUniqueVariables(List variableSet)
115 | {
116 | YP.addUniqueVariables(_arg1, variableSet);
117 | }
118 |
119 | public object makeCopy(Variable.CopyStore copyStore)
120 | {
121 | return new Functor1(_name, YP.makeCopy(_arg1, copyStore));
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/source/csharp/Functor3.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | using System;
32 | using System.Collections.Generic;
33 |
34 | namespace YieldProlog
35 | {
36 | public class Functor3 : IUnifiable
37 | {
38 | public readonly Atom _name;
39 | public readonly object _arg1;
40 | public readonly object _arg2;
41 | public readonly object _arg3;
42 |
43 | public Functor3(Atom name, object arg1, object arg2, object arg3)
44 | {
45 | _name = name;
46 | _arg1 = arg1;
47 | _arg2 = arg2;
48 | _arg3 = arg3;
49 | }
50 |
51 | public Functor3(string name, object arg1, object arg2, object arg3)
52 | : this(Atom.a(name), arg1, arg2, arg3)
53 | {
54 | }
55 |
56 | /// If arg is another Functor3, then succeed (yield once) if this and arg have the
57 | /// same name and all functor args unify, otherwise fail (don't yield).
58 | /// If arg is a Variable, then call its unify to unify with this.
59 | /// Otherwise fail (don't yield).
60 | public IEnumerable unify(object arg)
61 | {
62 | arg = YP.getValue(arg);
63 | if (arg is Functor3)
64 | {
65 | Functor3 argFunctor = (Functor3)arg;
66 | if (_name.Equals(argFunctor._name))
67 | {
68 | foreach (bool l1 in YP.unify(_arg1, argFunctor._arg1))
69 | {
70 | foreach (bool l2 in YP.unify(_arg2, argFunctor._arg2))
71 | {
72 | foreach (bool l3 in YP.unify(_arg3, argFunctor._arg3))
73 | yield return false;
74 | }
75 | }
76 | }
77 | }
78 | else if (arg is Variable)
79 | {
80 | foreach (bool l1 in ((Variable)arg).unify(this))
81 | yield return false;
82 | }
83 | }
84 |
85 | public override string ToString()
86 | {
87 | return _name + "(" + YP.getValue(_arg1) + ", " + YP.getValue(_arg2) + ", " +
88 | YP.getValue(_arg3) + ")";
89 | }
90 |
91 | public bool termEqual(object term)
92 | {
93 | term = YP.getValue(term);
94 | if (term is Functor3)
95 | {
96 | Functor3 termFunctor = (Functor3)term;
97 | return _name.Equals(termFunctor._name) && YP.termEqual(_arg1, termFunctor._arg1)
98 | && YP.termEqual(_arg2, termFunctor._arg2)
99 | && YP.termEqual(_arg3, termFunctor._arg3);
100 | }
101 | return false;
102 | }
103 |
104 | public override int GetHashCode()
105 | {
106 | // Note: The infrequent collision where changing the order of args gives the same hash value is OK.
107 | return _name.GetHashCode() ^ YP.getValue(_arg1).GetHashCode()
108 | ^ YP.getValue(_arg2).GetHashCode() ^ YP.getValue(_arg3).GetHashCode();
109 | }
110 |
111 | public bool lessThan(Functor3 functor)
112 | {
113 | // Do the equal check first since it is faster.
114 | if (!_name.Equals(functor._name))
115 | return _name.lessThan(functor._name);
116 |
117 | if (!YP.termEqual(_arg1, functor._arg1))
118 | return YP.termLessThan(_arg1, functor._arg1);
119 |
120 | if (!YP.termEqual(_arg2, functor._arg2))
121 | return YP.termLessThan(_arg2, functor._arg2);
122 |
123 | return YP.termLessThan(_arg3, functor._arg3);
124 | }
125 |
126 | public bool ground()
127 | {
128 | return YP.ground(_arg1) && YP.ground(_arg2) && YP.ground(_arg3);
129 | }
130 |
131 | public void addUniqueVariables(List variableSet)
132 | {
133 | YP.addUniqueVariables(_arg1, variableSet);
134 | YP.addUniqueVariables(_arg2, variableSet);
135 | YP.addUniqueVariables(_arg3, variableSet);
136 | }
137 |
138 | public object makeCopy(Variable.CopyStore copyStore)
139 | {
140 | return new Functor3(_name, YP.makeCopy(_arg1, copyStore),
141 | YP.makeCopy(_arg2, copyStore), YP.makeCopy(_arg3, copyStore));
142 | }
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/source/csharp/examples/Benchmarks/NaiveQueens.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using YieldProlog;
4 |
5 | namespace YieldPrologBenchmarks
6 | {
7 | class NaiveQueens
8 | {
9 | static void Main(string[] args)
10 | {
11 | long startTicks = DateTime.Now.Ticks;
12 | int nAnswers = 0;
13 | Variable Qs = new Variable();
14 | foreach (bool l1 in queens(11, Qs))
15 | {
16 | ++nAnswers;
17 | }
18 | long finishTicks = DateTime.Now.Ticks;
19 | Console.WriteLine("Naive queens: " +
20 | (finishTicks - startTicks) / 10000000.0 + " seconds, " + nAnswers + " answers");
21 |
22 | Console.WriteLine("\nPress Enter to finish.");
23 | Console.ReadLine();
24 | }
25 |
26 | static IEnumerable queens(object N, object Qs)
27 | {
28 | Variable Ns = new Variable();
29 | foreach (bool l1 in rangeList(1, N, Ns))
30 | {
31 | foreach (bool l2 in queens3(Ns, Atom.NIL, Qs))
32 | yield return false;
33 | }
34 | }
35 |
36 | static IEnumerable queens3(object UnplacedQs, object SafeQs, object Qs)
37 | {
38 | Variable UnplacedQs1 = new Variable();
39 | Variable Q = new Variable();
40 | foreach (bool l1 in selectq(Q, UnplacedQs, UnplacedQs1))
41 | {
42 | foreach (bool l2 in notHasAttack(Q, SafeQs))
43 | {
44 | foreach (bool l3 in queens3(UnplacedQs1, new ListPair(Q, SafeQs), Qs))
45 | yield return false;
46 | }
47 | }
48 | foreach (bool l1 in YP.unify(UnplacedQs, Atom.NIL))
49 | {
50 | foreach (bool l2 in YP.unify(Qs, SafeQs))
51 | yield return false;
52 | }
53 | }
54 |
55 | static IEnumerable notHasAttack(object X, object Xs)
56 | {
57 | foreach (bool l in attack(X, Xs))
58 | yield break;
59 |
60 | yield return false;
61 | }
62 |
63 | static IEnumerable attack(object X, object Xs)
64 | {
65 | foreach (bool l in attack3(X, 1, Xs))
66 | yield return false;
67 | }
68 |
69 | static IEnumerable attack3(object X, object N, object Arg3)
70 | {
71 | Variable Y = new Variable();
72 | foreach (bool l in new ListPair(Y, new Variable()).unify(Arg3))
73 | {
74 | if ((int)YP.getValue(X) == (int)Y.getValue() + (int)YP.getValue(N))
75 | yield return false;
76 | if ((int)YP.getValue(X) == (int)Y.getValue() - (int)YP.getValue(N))
77 | yield return false;
78 | }
79 | Variable Ys = new Variable();
80 | Variable N1 = new Variable();
81 | foreach (bool l1 in new ListPair(new Variable(), Ys).unify(Arg3))
82 | {
83 | foreach (bool l2 in N1.unify((int)YP.getValue(N) + 1))
84 | {
85 | foreach (bool l3 in attack3(X, N1, Ys))
86 | yield return false;
87 | }
88 | }
89 | }
90 |
91 | static IEnumerable rangeList(object M, object N, object List)
92 | {
93 | if ((int)YP.getValue(M) >= (int)YP.getValue(N))
94 | {
95 | foreach (bool l1 in YP.unify(List, new ListPair(N, Atom.NIL)))
96 | yield return false;
97 | }
98 | else
99 | {
100 | Variable Tail = new Variable();
101 | foreach (bool l1 in rangeList((int)YP.getValue(M) + 1, (int)YP.getValue(N), Tail))
102 | {
103 | foreach (bool l2 in YP.unify(List, new ListPair(M, Tail)))
104 | yield return false;
105 | }
106 | }
107 | }
108 |
109 | static IEnumerable selectq(object X, object Arg2, object Arg3)
110 | {
111 | foreach (bool l in new ListPair(X, Arg3).unify(Arg2))
112 | yield return false;
113 |
114 | Variable Y = new Variable();
115 | Variable Ys = new Variable();
116 | Variable Zs = new Variable();
117 | foreach (bool l1 in new ListPair(Y, Ys).unify(Arg2))
118 | {
119 | foreach (bool l2 in new ListPair(Y, Zs).unify(Arg3))
120 | {
121 | foreach (bool l3 in selectq(X, Ys, Zs))
122 | yield return false;
123 | }
124 | }
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/source/csharp/examples/Benchmarks/Queens.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using YieldProlog;
4 |
5 | namespace YieldPrologBenchmarks
6 | {
7 | class Queens
8 | {
9 | static void Main(string[] args)
10 | {
11 | long startTicks = DateTime.Now.Ticks;
12 | int nAnswers = 0;
13 | Variable Qs = new Variable();
14 | foreach (bool l1 in queens(11, Qs))
15 | {
16 | ++nAnswers;
17 | }
18 | long finishTicks = DateTime.Now.Ticks;
19 | Console.WriteLine("Optimized queens: " +
20 | (finishTicks - startTicks) / 10000000.0 + " seconds, " + nAnswers + " answers");
21 |
22 | Console.WriteLine("\nPress Enter to finish.");
23 | Console.ReadLine();
24 | }
25 |
26 | static IEnumerable queens(int N, Variable Qs)
27 | {
28 | Variable Ns = new Variable();
29 | foreach (bool l1 in rangeList(1, N, Ns))
30 | {
31 | foreach (bool l2 in queens3(Ns, Atom.NIL, Qs))
32 | yield return false;
33 | }
34 | }
35 |
36 | static IEnumerable queens3(object UnplacedQs, object SafeQs, Variable Qs)
37 | {
38 | ListPair UnplacedQsListPair = YP.getValue(UnplacedQs) as ListPair;
39 | if (UnplacedQsListPair != null)
40 | {
41 | Variable UnplacedQs1 = new Variable();
42 | Variable Q = new Variable();
43 | foreach (bool l1 in selectq(Q, UnplacedQsListPair, UnplacedQs1))
44 | {
45 | if (!(SafeQs is ListPair && hasAttack((int)Q.getValue(), (ListPair)SafeQs)))
46 | {
47 | foreach (bool l2 in queens3(UnplacedQs1, new ListPair(Q, SafeQs), Qs))
48 | yield return false;
49 | }
50 | }
51 | }
52 | else
53 | {
54 | foreach (bool l1 in Qs.unify(SafeQs))
55 | yield return false;
56 | }
57 | }
58 |
59 | static bool hasAttack(int X, ListPair Xs)
60 | {
61 | return hasAttack3(X, 1, Xs);
62 | }
63 |
64 | static bool hasAttack3(int X, int N, ListPair Arg3)
65 | {
66 | if (X == (int)YP.getValue(Arg3._arg1) + N || X == (int)YP.getValue(Arg3._arg1) - N)
67 | return true;
68 | if (Arg3._arg2 is ListPair)
69 | return hasAttack3(X, N + 1, (ListPair)YP.getValue(Arg3._arg2));
70 | else
71 | return false;
72 | }
73 |
74 | static IEnumerable rangeList(int M, int N, Variable List)
75 | {
76 | if (M >= N)
77 | {
78 | foreach (bool l1 in List.unify(new ListPair(N, Atom.NIL)))
79 | yield return false;
80 | }
81 | else
82 | {
83 | Variable Tail = new Variable();
84 | foreach (bool l1 in rangeList(M + 1, N, Tail))
85 | {
86 | foreach (bool l2 in List.unify(new ListPair(M, Tail)))
87 | yield return false;
88 | }
89 | }
90 | }
91 |
92 | static IEnumerable selectq(Variable X, ListPair Arg2, Variable Arg3)
93 | {
94 | foreach (bool l1 in X.unify(Arg2._arg1))
95 | {
96 | foreach (bool l2 in Arg3.unify(Arg2._arg2))
97 | yield return false;
98 | }
99 |
100 | ListPair Arg2Tail = YP.getValue(Arg2._arg2) as ListPair;
101 | if (Arg2Tail != null)
102 | {
103 | Variable Zs = new Variable();
104 | foreach (bool l1 in selectq(X, Arg2Tail, Zs))
105 | {
106 | foreach (bool l2 in Arg3.unify(new ListPair(Arg2._arg1, Zs)))
107 | yield return false;
108 | }
109 | }
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/source/csharp/examples/Benchmarks/YieldPrologBenchmarks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Debug
4 | AnyCPU
5 | 9.0.21022
6 | 2.0
7 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}
8 | Exe
9 | Properties
10 | YieldPrologBenchmarks
11 | YieldPrologBenchmarks
12 | YieldPrologBenchmarks.Queens
13 |
14 |
15 | 2.0
16 | v2.0
17 |
18 |
19 | publish\
20 | true
21 | Disk
22 | false
23 | Foreground
24 | 7
25 | Days
26 | false
27 | false
28 | true
29 | 0
30 | 1.0.0.%2a
31 | false
32 | false
33 | true
34 |
35 |
36 | true
37 | full
38 | false
39 | bin\Debug\
40 | DEBUG;TRACE
41 | prompt
42 | 4
43 |
44 |
45 | pdbonly
46 | true
47 | bin\Release\
48 | TRACE
49 | prompt
50 | 4
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Atom.cs
60 |
61 |
62 | BagofAnswers.cs
63 |
64 |
65 | Compiler.cs
66 |
67 |
68 | FindallAnswers.cs
69 |
70 |
71 | Functor.cs
72 |
73 |
74 | Functor1.cs
75 |
76 |
77 | Functor2.cs
78 |
79 |
80 | Functor3.cs
81 |
82 |
83 | IndexedAnswers.cs
84 |
85 |
86 | ListPair.cs
87 |
88 |
89 | Parser.cs
90 |
91 |
92 | PrologException.cs
93 |
94 |
95 | Variable.cs
96 |
97 |
98 | YP.cs
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | False
107 | .NET Framework 2.0 %28x86%29
108 | false
109 |
110 |
111 | False
112 | .NET Framework 3.0 %28x86%29
113 | false
114 |
115 |
116 | False
117 | .NET Framework 3.5
118 | true
119 |
120 |
121 | False
122 | Windows Installer 3.1
123 | true
124 |
125 |
126 |
127 |
128 |
129 |
130 |
137 |
--------------------------------------------------------------------------------
/source/csharp/examples/Benchmarks/YieldPrologBenchmarks.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | en-US
14 | false
15 |
16 |
--------------------------------------------------------------------------------
/source/csharp/examples/Benchmarks/YieldPrologBenchmarks.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual C# Express 2008
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YieldPrologBenchmarks", "YieldPrologBenchmarks.csproj", "{5686A38F-64AD-40C0-99AD-9CD4322F6179}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/source/csharp/examples/Benchmarks/YieldPrologBenchmarks.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vslab/YieldProlog/11f68cd05d55a8b56681b1c7572b9067e7816915/source/csharp/examples/Benchmarks/YieldPrologBenchmarks.suo
--------------------------------------------------------------------------------
/source/csharp/examples/Benchmarks/monomake.bat:
--------------------------------------------------------------------------------
1 | rem This is a simple make file to compile a Yield Prolog program into a .exe file under Mono.
2 | rem For example, type: monomake YPShell.cs
3 | gmcs %1 ..\..\Atom.cs ..\..\BagofAnswers.cs ..\..\Compiler.cs ..\..\FindallAnswers.cs ..\..\Functor.cs ..\..\Functor1.cs ..\..\Functor2.cs ..\..\Functor3.cs ..\..\IndexedAnswers.cs ..\..\ListPair.cs ..\..\Parser.cs ..\..\PrologException.cs ..\..\Variable.cs ..\..\YP.cs
--------------------------------------------------------------------------------
/source/csharp/examples/YPShell/YPShell.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Collections.Generic;
4 | using YieldProlog;
5 |
6 | ///
7 | /// YPShell has a Main function that provides a command prompt to evaluate Prolog statements
8 | /// and display the results.
9 | ///
10 | public class YPShell
11 | {
12 | static void Main(string[] args)
13 | {
14 | Console.WriteLine("Yield Prolog Shell. Enter ctrl-Z to exit.");
15 |
16 | while (true)
17 | {
18 | Console.Write("?- ");
19 | string goalString = Console.ReadLine();
20 | if (goalString == null)
21 | break;
22 | if (goalString == "")
23 | {
24 | Console.WriteLine("Enter ctrl-Z to exit.");
25 | continue;
26 | }
27 |
28 | Variable Goal = new Variable();
29 | Variable VariableList = new Variable();
30 | foreach (bool l1 in parseGoal(goalString, Goal, VariableList))
31 | {
32 | try
33 | {
34 | bool gotMatch = false;
35 | foreach (bool l2 in YP.getIterator(Goal, null))
36 | {
37 | gotMatch = true;
38 | if (YP.getValue(VariableList) != Atom.NIL)
39 | {
40 | // We are showing values, so allow the user to enter ";" to display the next match.
41 | writeValues(VariableList);
42 | if (!Console.ReadLine().StartsWith(";"))
43 | break;
44 | }
45 | }
46 |
47 | if (gotMatch)
48 | {
49 | if (YP.getValue(VariableList) == Atom.NIL)
50 | // We didn't show any values. So just write true after matching (one or more times).
51 | Console.WriteLine("true");
52 | }
53 | else
54 | Console.WriteLine("fail");
55 | }
56 | catch (PrologException exception)
57 | {
58 | Console.WriteLine(exception._term.ToString());
59 | }
60 | }
61 | }
62 | }
63 |
64 | ///
65 | /// Parse goalString and yield for each Goal, setting VariableList to a list of
66 | /// (variableAtom = Var).
67 | ///
68 | ///
69 | ///
70 | ///
71 | ///
72 | static IEnumerable parseGoal(string goalString, object Goal, object VariableList)
73 | {
74 | // The parser requires a newline at the end.
75 | YP.see(new StringReader(goalString + "\n"));
76 | object TermList = new Variable();
77 | // parseInput set TermList to a list of f(Goal, VariableList).
78 | foreach (bool l1 in Parser.parseInput(TermList))
79 | {
80 | // Close the input now before yielding.
81 | YP.seen();
82 | // Iterate through each member of TermList.
83 | for (TermList = YP.getValue(TermList);
84 | TermList is Functor2 && ((Functor2)TermList)._name == Atom.DOT;
85 | TermList = YP.getValue(((Functor2)TermList)._arg2))
86 | {
87 | // Unify the head of the list with f(Goal, VariableList).
88 | foreach (bool l2 in YP.unify
89 | (((Functor2)TermList)._arg1, new Functor2(Atom.F, Goal, VariableList)))
90 | yield return false;
91 | }
92 | yield break;
93 | }
94 | // Close the input in case parseInput failed.
95 | YP.seen();
96 | }
97 |
98 | ///
99 | /// Write out each entry in VariableList which is a list of (variableAtom = Var)
100 | ///
101 | ///
102 | static void writeValues(object VariableList)
103 | {
104 | for (VariableList = YP.getValue(VariableList);
105 | VariableList is Functor2 && ((Functor2)VariableList)._name == Atom.DOT;
106 | VariableList = YP.getValue(((Functor2)VariableList)._arg2))
107 | {
108 | Functor2 variableAndValue = YP.getValue(((Functor2)VariableList)._arg1) as Functor2;
109 | if (variableAndValue != null)
110 | {
111 | Console.WriteLine("");
112 | Console.Write(YP.getValue(variableAndValue._arg1));
113 | Console.Write(" = ");
114 | Console.Write(YP.getValue(variableAndValue._arg2));
115 | }
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/source/csharp/examples/YPShell/YPShell.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Debug
4 | AnyCPU
5 | 9.0.21022
6 | 2.0
7 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}
8 | Exe
9 | Properties
10 | YPShell
11 | YPShell
12 | YPShell
13 |
14 |
15 | 2.0
16 | v2.0
17 |
18 |
19 | false
20 | publish\
21 | true
22 | Disk
23 | false
24 | Foreground
25 | 7
26 | Days
27 | false
28 | false
29 | true
30 | 0
31 | 1.0.0.%2a
32 | false
33 | true
34 |
35 |
36 | true
37 | full
38 | false
39 | bin\Debug\
40 | DEBUG;TRACE
41 | prompt
42 | 4
43 |
44 |
45 | pdbonly
46 | true
47 | bin\Release\
48 | TRACE
49 | prompt
50 | 4
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Atom.cs
60 |
61 |
62 | BagofAnswers.cs
63 |
64 |
65 | Compiler.cs
66 |
67 |
68 | FindallAnswers.cs
69 |
70 |
71 | Functor.cs
72 |
73 |
74 | Functor1.cs
75 |
76 |
77 | Functor2.cs
78 |
79 |
80 | Functor3.cs
81 |
82 |
83 | IndexedAnswers.cs
84 |
85 |
86 | ListPair.cs
87 |
88 |
89 | Parser.cs
90 |
91 |
92 | PrologException.cs
93 |
94 |
95 | Variable.cs
96 |
97 |
98 | YP.cs
99 |
100 |
101 |
102 |
103 |
104 | False
105 | .NET Framework 2.0 %28x86%29
106 | false
107 |
108 |
109 | False
110 | .NET Framework 3.0 %28x86%29
111 | false
112 |
113 |
114 | False
115 | .NET Framework 3.5
116 | true
117 |
118 |
119 | False
120 | Windows Installer 3.1
121 | true
122 |
123 |
124 |
125 |
126 |
127 |
128 |
135 |
--------------------------------------------------------------------------------
/source/csharp/examples/YPShell/YPShell.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 | publish\
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | en-US
13 | false
14 |
15 |
--------------------------------------------------------------------------------
/source/csharp/examples/YPShell/YPShell.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual C# Express 2008
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YPShell", "YPShell.csproj", "{5686A38F-64AD-40C0-99AD-9CD4322F6179}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {5686A38F-64AD-40C0-99AD-9CD4322F6179}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/source/csharp/examples/YPShell/YPShell.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vslab/YieldProlog/11f68cd05d55a8b56681b1c7572b9067e7816915/source/csharp/examples/YPShell/YPShell.suo
--------------------------------------------------------------------------------
/source/csharp/examples/YPShell/monomake.bat:
--------------------------------------------------------------------------------
1 | rem This is a simple make file to compile a Yield Prolog program into a .exe file under Mono.
2 | rem For example, type: monomake YPShell.cs
3 | gmcs %1 ..\..\Atom.cs ..\..\BagofAnswers.cs ..\..\Compiler.cs ..\..\FindallAnswers.cs ..\..\Functor.cs ..\..\Functor1.cs ..\..\Functor2.cs ..\..\Functor3.cs ..\..\IndexedAnswers.cs ..\..\ListPair.cs ..\..\Parser.cs ..\..\PrologException.cs ..\..\Variable.cs ..\..\YP.cs
--------------------------------------------------------------------------------
/source/csharp/examples/YieldPrologTutorial/Tutorial2.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | using System;
32 | using System.Collections.Generic;
33 | using YieldProlog;
34 |
35 | // This is the code for tutorial2.html in the doc directory.
36 | class Tutorial2
37 | {
38 | static void Main(string[] args)
39 | {
40 | Console.WriteLine("Find relations:");
41 | Variable Brother = new Variable();
42 | foreach (bool l1 in brother("Hillary", Brother))
43 | Console.WriteLine("Hillary has brother " +
44 | Brother.getValue() + ".");
45 |
46 | Console.WriteLine("Check if it is square:");
47 | foreach (bool l1 in squaredRectangle(10, 10))
48 | Console.WriteLine("10 by 10 rectangle is square.");
49 |
50 | Console.WriteLine("Make it square:");
51 | Variable Width = new Variable();
52 | Variable Height = new Variable();
53 | foreach (bool l1 in Width.unify(10))
54 | {
55 | foreach (bool l2 in squaredRectangle(Width, Height))
56 | Console.WriteLine("A square of width " +
57 | Width.getValue() + " has height " +
58 | Height.getValue() + ".");
59 | }
60 |
61 | Console.WriteLine("Make it square before we know the width:");
62 | foreach (bool l1 in squaredRectangle(Width, Height))
63 | {
64 | foreach (bool l2 in Width.unify(10))
65 | Console.WriteLine("A square of width " +
66 | Width.getValue() + " has height " +
67 | Height.getValue() + ".");
68 | }
69 |
70 | Console.WriteLine("Get one match:");
71 | foreach (bool l1 in anyBrother("Hillary", Brother))
72 | Console.WriteLine("Hillary has a brother " +
73 | Brother.getValue() + ".");
74 | foreach (bool l1 in anyBrother("Bill", Brother))
75 | Console.WriteLine("Bill has a brother " +
76 | Brother.getValue() + ".");
77 |
78 | Console.WriteLine("Use cut for negation:");
79 | foreach (bool l1 in noBrother("Hillary"))
80 | Console.WriteLine("Hillary has no brother.");
81 | foreach (bool l1 in noBrother("Chelsea"))
82 | Console.WriteLine("Chelsea has no brother.");
83 |
84 | Console.WriteLine("\nPress Enter to finish.");
85 | Console.ReadLine();
86 | }
87 |
88 | static IEnumerable brother(object Person, object Brother)
89 | {
90 | foreach (bool l1 in YP.unify(Person, "Hillary"))
91 | {
92 | foreach (bool l2 in YP.unify(Brother, "Tony"))
93 | yield return false;
94 | foreach (bool l2 in YP.unify(Brother, "Hugh"))
95 | yield return false;
96 | }
97 | foreach (bool l1 in YP.unify(Person, "Bill"))
98 | {
99 | foreach (bool l2 in YP.unify(Brother, "Roger"))
100 | yield return false;
101 | }
102 | }
103 |
104 | static IEnumerable squaredRectangle(object Width, object Height)
105 | {
106 | foreach (bool l1 in YP.unify(Width, Height))
107 | yield return false;
108 | }
109 |
110 | static IEnumerable anyBrother(object Person, object Brother)
111 | {
112 | foreach (bool l1 in brother(Person, Brother))
113 | {
114 | yield return false;
115 | break;
116 | }
117 | }
118 |
119 | static IEnumerable noBrother(object Person)
120 | {
121 | Variable Brother = new Variable();
122 | foreach (bool l1 in brother(Person, Brother))
123 | yield break;
124 | yield return false;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/source/csharp/examples/YieldPrologTutorial/Tutorial3.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | using System;
32 | using System.Collections.Generic;
33 | using YieldProlog;
34 |
35 | // This is the code for tutorial3.html in the doc directory.
36 | class Tutorial3
37 | {
38 | static void Main(string[] args)
39 | {
40 | Console.WriteLine("Return a list of 2 elements:");
41 | Variable List = new Variable();
42 | foreach (bool l1 in makeList("a", "b", List))
43 | Console.WriteLine("List = " + List.getValue());
44 |
45 | Console.WriteLine("Unify two lists:");
46 | Variable Second = new Variable();
47 | foreach (bool l1 in makeList("x", Second, new ListPair("x", new ListPair("y", Atom.NIL))))
48 | Console.WriteLine("The second element is " + Second.getValue());
49 |
50 | Console.WriteLine("\nPress Enter to finish.");
51 | Console.ReadLine();
52 | }
53 |
54 | static IEnumerable makeList(object First, object Second, object List)
55 | {
56 | ListPair list1 = new ListPair(Second, Atom.NIL);
57 | ListPair result = new ListPair(First, list1);
58 | foreach (bool l1 in YP.unify(List, result))
59 | yield return false;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/source/csharp/examples/YieldPrologTutorial/YieldPrologTutorial.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Debug
4 | AnyCPU
5 | 9.0.21022
6 | 2.0
7 | {ACD390C7-09EB-4106-978F-26DF9DB2D03B}
8 | Exe
9 | Properties
10 | YieldPrologTutorial
11 | YieldPrologTutorial
12 | Tutorial1
13 |
14 |
15 | 2.0
16 | v2.0
17 |
18 |
19 | publish\
20 | true
21 | Disk
22 | false
23 | Foreground
24 | 7
25 | Days
26 | false
27 | false
28 | true
29 | 0
30 | 1.0.0.%2a
31 | false
32 | false
33 | true
34 |
35 |
36 | true
37 | full
38 | false
39 | bin\Debug\
40 | DEBUG;TRACE
41 | prompt
42 | 4
43 |
44 |
45 | pdbonly
46 | true
47 | bin\Release\
48 | TRACE
49 | prompt
50 | 4
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Atom.cs
60 |
61 |
62 | BagofAnswers.cs
63 |
64 |
65 | Compiler.cs
66 |
67 |
68 | FindallAnswers.cs
69 |
70 |
71 | Functor.cs
72 |
73 |
74 | Functor1.cs
75 |
76 |
77 | Functor2.cs
78 |
79 |
80 | Functor3.cs
81 |
82 |
83 | IndexedAnswers.cs
84 |
85 |
86 | ListPair.cs
87 |
88 |
89 | Parser.cs
90 |
91 |
92 | PrologException.cs
93 |
94 |
95 | Variable.cs
96 |
97 |
98 | YP.cs
99 |
100 |
101 | Code
102 |
103 |
104 |
105 | Code
106 |
107 |
108 |
109 |
110 |
111 | False
112 | .NET Framework 2.0 %28x86%29
113 | false
114 |
115 |
116 | False
117 | .NET Framework 3.0 %28x86%29
118 | false
119 |
120 |
121 | False
122 | .NET Framework 3.5
123 | true
124 |
125 |
126 | False
127 | Windows Installer 3.1
128 | true
129 |
130 |
131 |
132 |
133 |
134 |
135 |
142 |
--------------------------------------------------------------------------------
/source/csharp/examples/YieldPrologTutorial/YieldPrologTutorial.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | en-US
14 | false
15 |
16 |
--------------------------------------------------------------------------------
/source/csharp/examples/YieldPrologTutorial/YieldPrologTutorial.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 10.00
3 | # Visual C# Express 2008
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YieldPrologTutorial", "YieldPrologTutorial.csproj", "{ACD390C7-09EB-4106-978F-26DF9DB2D03B}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Any CPU = Debug|Any CPU
9 | Release|Any CPU = Release|Any CPU
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {ACD390C7-09EB-4106-978F-26DF9DB2D03B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
13 | {ACD390C7-09EB-4106-978F-26DF9DB2D03B}.Debug|Any CPU.Build.0 = Debug|Any CPU
14 | {ACD390C7-09EB-4106-978F-26DF9DB2D03B}.Release|Any CPU.ActiveCfg = Release|Any CPU
15 | {ACD390C7-09EB-4106-978F-26DF9DB2D03B}.Release|Any CPU.Build.0 = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/source/csharp/examples/YieldPrologTutorial/YieldPrologTutorial.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vslab/YieldProlog/11f68cd05d55a8b56681b1c7572b9067e7816915/source/csharp/examples/YieldPrologTutorial/YieldPrologTutorial.suo
--------------------------------------------------------------------------------
/source/csharp/examples/YieldPrologTutorial/monomake.bat:
--------------------------------------------------------------------------------
1 | rem This is a simple make file to compile a Yield Prolog program into a .exe file under Mono.
2 | rem For example, type: monomake YPShell.cs
3 | gmcs %1 ..\..\Atom.cs ..\..\BagofAnswers.cs ..\..\Compiler.cs ..\..\FindallAnswers.cs ..\..\Functor.cs ..\..\Functor1.cs ..\..\Functor2.cs ..\..\Functor3.cs ..\..\IndexedAnswers.cs ..\..\ListPair.cs ..\..\Parser.cs ..\..\PrologException.cs ..\..\Variable.cs ..\..\YP.cs
--------------------------------------------------------------------------------
/source/csharp/update.bat:
--------------------------------------------------------------------------------
1 | rem Copy makefiles from the main working directory YPShell.
2 | copy examples\YPShell\monomake.bat examples\Benchmarks
3 | copy examples\YPShell\monomake.bat examples\YieldPrologTutorial
4 |
5 | rem Copy executables to bin
6 | copy examples\YPShell\bin\Release\YPShell.exe ..\..\bin
7 |
--------------------------------------------------------------------------------
/source/javascript/Atom.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | // You should not call this constructor, but use Atom.a instead.
32 | function Atom(name, module) {
33 | this._name = name;
34 | if (module == undefined)
35 | this._module = null;
36 | else
37 | this._module = module;
38 | }
39 |
40 | Atom._atomStore = new Object();
41 | // Return an Atom object with the name and module. If module is null or Atom.NIL,
42 | // this behaves like Atom.a(name, undefined) and returns the unique object where the module is null.
43 | // If module is null or Atom.NIL, return a unique Atom object.
44 | // If module is not null or Atom.NIL, this may or may not be the same object as another Atom
45 | // with the same name and module.
46 | // You should use this to create an Atom instead of calling the Atom constructor.
47 | Atom.a = function(name, module) {
48 | if (module == undefined || module == null || module == Atom.NIL) {
49 | var atom = Atom._atomStore[name];
50 | if (atom === undefined) {
51 | atom = new Atom(name);
52 | Atom._atomStore[name] = atom;
53 | }
54 | return atom;
55 | }
56 | else
57 | return new Atom(name, module);
58 | }
59 |
60 | // If Obj is an Atom unify its _module with Module. If the Atom's _module is null, use Atom.NIL.
61 | Atom.module = function(Obj, Module) {
62 | Obj = YP.getValue(Obj);
63 | if (Obj instanceof Atom) {
64 | if (Obj._module == null)
65 | return YP.unify(Module, Atom.NIL);
66 | else
67 | return YP.unify(Module, Obj._module);
68 | }
69 | return YP.fail();
70 | }
71 |
72 | Atom.NIL = Atom.a("[]");
73 | Atom.DOT = Atom.a(".");
74 | Atom.F = Atom.a("f");
75 | Atom.SLASH = Atom.a("/");
76 | Atom.HAT = Atom.a("^");
77 | Atom.RULE = Atom.a(":-");
78 | Atom.TRUE = Atom.a("true");
79 |
80 | Atom.prototype.unify = function(arg)
81 | {
82 | arg = YP.getValue(arg);
83 | if (arg instanceof Atom)
84 | return this.equals(arg) ? YP.succeed() : YP.fail();
85 | else if (arg instanceof Variable)
86 | return arg.unify(this);
87 | else
88 | return YP.fail();
89 | }
90 |
91 | Atom.prototype.addUniqueVariables = function(variableSet)
92 | {
93 | // Atom does not contain variables.
94 | }
95 |
96 | Atom.prototype.makeCopy = function(copyStore)
97 | {
98 | // Atom does not contain variables that need to be copied.
99 | return this;
100 | }
101 |
102 | Atom.prototype.termEqual = function(term)
103 | {
104 | return this.equals(YP.getValue(term));
105 | }
106 |
107 | Atom.prototype.ground = function()
108 | {
109 | // Atom is always ground.
110 | return true;
111 | }
112 |
113 | Atom.prototype.equals = function(obj) {
114 | if (obj instanceof Atom) {
115 | if (this._module == null && obj._module == null)
116 | // When _declaringClass is null, we always use an identical object from _atomStore.
117 | return this == obj;
118 | // Otherwise, ignore _declaringClass and do a normal string compare on the _name.
119 | return this._name == obj._name;
120 | }
121 | return false;
122 | }
123 |
124 | Atom.prototype.toString = function() {
125 | return this._name;
126 | }
127 |
128 | Atom.prototype.toQuotedString = function() {
129 | if (this._name.length == 0)
130 | return "''";
131 | else if (this == Atom.NIL)
132 | return "[]";
133 |
134 | var result = new Array("");
135 | var useQuotes = false;
136 | for each (var c in this._name) {
137 | if (c == '\'') {
138 | result.push("''");
139 | useQuotes = true;
140 | }
141 | else if (c == '_' || c >= 'a' && c <= 'z' ||
142 | c >= 'A' && c <= 'Z' || c >= '0' && c <= '9')
143 | result.push(c);
144 | else {
145 | // Debug: Need to handle non-printable chars.
146 | result.push(c);
147 | useQuotes = true;
148 | }
149 | }
150 |
151 | if (!useQuotes && this._name[0] >= 'a' && this._name[0] <= 'z')
152 | return result.join("");
153 | else
154 | // Surround in single quotes.
155 | result.push('\'');
156 | return "'" + result.join("");
157 | }
158 |
159 |
160 | // Return true if _name is lexicographically less than atom._name.
161 | Atom.prototype.lessThan = function(atom) {
162 | return this._name < atom._name;
163 | }
164 |
--------------------------------------------------------------------------------
/source/javascript/FindallAnswers.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | // A FindallAnswers holds answers for findall.
32 | function FindallAnswers(Template) {
33 | this._template = Template;
34 | this._bagArray = [];
35 | }
36 |
37 | FindallAnswers.prototype.add = function() {
38 | this._bagArray.push(YP.makeCopy(this._template, new Variable.CopyStore()));
39 | }
40 |
41 | FindallAnswers.prototype.resultArray = function() {
42 | return this._bagArray;
43 | }
44 |
45 | // Unify Bag with the result. This frees the internal answers, so you can only call this once.
46 | FindallAnswers.prototype.result = function(Bag) {
47 | var result = ListPair.make(this._bagArray);
48 | // Try to free the memory.
49 | this._bagArray = null;
50 | return YP.unify(Bag, result);
51 | }
52 |
53 | // This is a simplified findall when the goal is a single call.
54 | FindallAnswers.findall = function(Template, goal, Bag) {
55 | var findallAnswers = new FindallAnswers(Template);
56 | for each (var l1 in goal)
57 | findallAnswers.add();
58 | return findallAnswers.result(Bag);
59 | }
60 |
61 | // Like findall, except return an array of the results.
62 | FindallAnswers.findallArray = function(Template, goal) {
63 | var findallAnswers = new FindallAnswers(Template);
64 | for each (var l1 in goal)
65 | findallAnswers.add();
66 | return findallAnswers.resultArray();
67 | }
68 |
--------------------------------------------------------------------------------
/source/javascript/Functor.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | function Functor(name, args) {
32 | if (args.length < 3)
33 | {
34 | if (args.length == 0)
35 | throw "For arity 0 functor, just use name as an Atom";
36 | else if (args.length == 1)
37 | throw "For arity 1 functor, use Functor1";
38 | else if (args.length == 2)
39 | throw "For arity 2 functor, use Functor2";
40 | else if (args.length == 3)
41 | throw "For arity 3 functor, use Functor3";
42 | else
43 | // (This shouldn't happen, but include it for completeness.
44 | throw "Cannot create a Functor of arity " + args.length;
45 | }
46 |
47 | if (name instanceof Atom)
48 | this._name = name;
49 | else
50 | // Assume name is a string.
51 | this._name = Atom.a(name);
52 | this._args = args;
53 | }
54 |
55 | // Return an Atom, Functor1, Functor2, Functor3 or Functor depending on the
56 | // length of args.
57 | // Note that this is different than the Functor constructor which requires
58 | // the length of args to be greater than 3.
59 | Functor.make = function(name, args) {
60 | if (!(name instanceof Atom))
61 | // Assume name is a string.
62 | name = Atom.a(name);
63 |
64 | if (args.length <= 0)
65 | return name;
66 | else if (args.length == 1)
67 | return new Functor1(name, args[0]);
68 | else if (args.length == 2)
69 | return new Functor2(name, args[0], args[1]);
70 | else if (args.length == 3)
71 | return new Functor3(name, args[0], args[1], args[2]);
72 | else
73 | return new Functor(name, args);
74 | }
75 |
76 | // If arg is another Functor, then succeed (yield once) if this and arg have the
77 | // same name and all functor args unify, otherwise fail (don't yield).
78 | // If arg is a Variable, then call its unify to unify with this.
79 | // Otherwise fail (don't yield).
80 | Functor.prototype.unify = function(arg) {
81 | arg = YP.getValue(arg);
82 | if (arg instanceof Functor)
83 | {
84 | if (this._name.equals(arg._name))
85 | return YP.unifyArrays(this._args, arg._args);
86 | else
87 | return YP.fail();
88 | }
89 | else if (arg instanceof Variable)
90 | return arg.unify(this);
91 | else
92 | return YP.fail();
93 | }
94 |
95 | Functor.prototype.toString = function() {
96 | var result = this._name + "(" + YP.getValue(this._args[0]);
97 | for (var i = 1; i < this._args.length; ++i)
98 | result += ", " + YP.getValue(this._args[i]);
99 | result += ")";
100 | return result;
101 | }
102 |
103 | Functor.prototype.termEqual = function(term) {
104 | term = YP.getValue(term);
105 | if (term instanceof Functor) {
106 | if (this._name.equals(term._name) && this._args.length == term._args.length) {
107 | for (var i = 0; i < this._args.length; ++i)
108 | {
109 | if (!YP.termEqual(this._args[i], term._args[i]))
110 | return false;
111 | }
112 | return true;
113 | }
114 | }
115 | return false;
116 | }
117 |
118 | Functor.prototype.lessThan = function(functor) {
119 | // Do the equal check first since it is faster.
120 | if (!this._name.equals(functor._name))
121 | return this._name.lessThan(functor._name);
122 |
123 | if (this._args.length != functor._args.length)
124 | return this._args.length < functor._args.length;
125 |
126 | for (var i = 0; i < this._args.length; ++i) {
127 | if (!YP.termEqual(this._args[i], functor._args[i]))
128 | return YP.termLessThan(this._args[i], functor._args[i]);
129 | }
130 |
131 | return false;
132 | }
133 |
134 | Functor.prototype.ground = function() {
135 | for (var i = 0; i < this._args.length; ++i) {
136 | if (!YP.ground(this._args[i]))
137 | return false;
138 | }
139 | return true;
140 | }
141 |
142 | Functor.prototype.addUniqueVariables = function(variableSet) {
143 | for (var i = 0; i < this._args.length; ++i)
144 | YP.addUniqueVariables(this._args[i], variableSet);
145 | }
146 |
147 | Functor.prototype.makeCopy = function(copyStore) {
148 | var argsCopy = [YP.makeCopy(arg, copyStore) for each (arg in this._args)];
149 | return new Functor(this._name, argsCopy);
150 | }
151 |
152 |
--------------------------------------------------------------------------------
/source/javascript/Functor1.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | function Functor1(name, arg1) {
32 | if (name instanceof Atom)
33 | this._name = name;
34 | else
35 | // Assume name is a string.
36 | this._name = Atom.a(name);
37 | this._arg1 = arg1;
38 | }
39 |
40 | // If arg is another Functor1, then succeed (yield once) if this and arg have the
41 | // same name and the functor args unify, otherwise fail (don't yield).
42 | // If arg is a Variable, then call its unify to unify with this.
43 | // Otherwise fail (don't yield).
44 | Functor1.prototype.unify = function(arg) {
45 | arg = YP.getValue(arg);
46 | if (arg instanceof Functor1)
47 | {
48 | if (this._name.equals(arg._name)) {
49 | for each (var l1 in YP.unify(this._arg1, arg._arg1))
50 | yield false;
51 | }
52 | }
53 | else if (arg instanceof Variable) {
54 | for each (var l1 in arg.unify(this))
55 | yield false;
56 | }
57 | }
58 |
59 | Functor1.prototype.toString = function() {
60 | return this._name + "(" + YP.getValue(this._arg1) + ")";
61 | }
62 |
63 | Functor1.prototype.termEqual = function(term) {
64 | term = YP.getValue(term);
65 | if (term instanceof Functor1)
66 | return this._name.equals(term._name) && YP.termEqual(this._arg1, term._arg1);
67 | return false;
68 | }
69 |
70 | Functor1.prototype.lessThan = function(functor) {
71 | // Do the equal check first since it is faster.
72 | if (!this._name.equals(functor._name))
73 | return this._name.lessThan(functor._name);
74 |
75 | return YP.termLessThan(this._arg1, functor._arg1);
76 | }
77 |
78 | Functor1.prototype.ground = function() {
79 | return YP.ground(this._arg1);
80 | }
81 |
82 | Functor1.prototype.addUniqueVariables = function(variableSet) {
83 | YP.addUniqueVariables(this._arg1, variableSet);
84 | }
85 |
86 | Functor1.prototype.makeCopy = function(copyStore) {
87 | return new Functor1(this._name, YP.makeCopy(this._arg1, copyStore));
88 | }
89 |
90 |
--------------------------------------------------------------------------------
/source/javascript/Functor2.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | function Functor2(name, arg1, arg2) {
32 | if (name instanceof Atom)
33 | this._name = name;
34 | else
35 | // Assume name is a string.
36 | this._name = Atom.a(name);
37 | this._arg1 = arg1;
38 | this._arg2 = arg2;
39 | }
40 |
41 | // If arg is another Functor2, then succeed (yield once) if this and arg have the
42 | // same name and all functor args unify, otherwise fail (don't yield).
43 | // If arg is a Variable, then call its unify to unify with this.
44 | // Otherwise fail (don't yield).
45 | Functor2.prototype.unify = function(arg) {
46 | arg = YP.getValue(arg);
47 | if (arg instanceof Functor2)
48 | {
49 | if (this._name.equals(arg._name)) {
50 | for each (var l1 in YP.unify(this._arg1, arg._arg1)) {
51 | for each (var l1 in YP.unify(this._arg2, arg._arg2))
52 | yield false;
53 | }
54 | }
55 | }
56 | else if (arg instanceof Variable) {
57 | for each (var l1 in arg.unify(this))
58 | yield false;
59 | }
60 | }
61 |
62 | Functor2.prototype.toString = function() {
63 | if (this._name == Atom.DOT)
64 | return Functor2.listPairToString(this);
65 | else
66 | return this._name + "(" + YP.getValue(this._arg1) + ", " + YP.getValue(this._arg2) + ")";
67 | }
68 |
69 | Functor2.prototype.termEqual = function(term) {
70 | term = YP.getValue(term);
71 | if (term instanceof Functor2)
72 | return this._name.equals(term._name) && YP.termEqual(this._arg1, term._arg1) &&
73 | YP.termEqual(this._arg2, term._arg2);
74 | return false;
75 | }
76 |
77 | Functor2.prototype.lessThan = function(functor) {
78 | // Do the equal check first since it is faster.
79 | if (!this._name.equals(functor._name))
80 | return this._name.lessThan(functor._name);
81 |
82 | if (!YP.termEqual(this._arg1, functor._arg1))
83 | return YP.termLessThan(this._arg1, functor._arg1);
84 |
85 | return YP.termLessThan(this._arg2, functor._arg2);
86 | }
87 |
88 | Functor2.prototype.ground = function() {
89 | return YP.ground(this._arg1) && YP.ground(this._arg2);
90 | }
91 |
92 | Functor2.prototype.addUniqueVariables = function(variableSet) {
93 | YP.addUniqueVariables(this._arg1, variableSet);
94 | YP.addUniqueVariables(this._arg2, variableSet);
95 | }
96 |
97 | Functor2.prototype.makeCopy = function(copyStore) {
98 | return new Functor2(this._name, YP.makeCopy(this._arg1, copyStore),
99 | YP.makeCopy(this._arg2, copyStore));
100 | }
101 |
102 | Functor2.listPairToString = function(listPair) {
103 | var result = "[";
104 | while (true) {
105 | var head = YP.getValue(listPair._arg1);
106 | var tail = YP.getValue(listPair._arg2);
107 | if (tail == Atom.NIL) {
108 | result += "" + head;
109 | break;
110 | }
111 | else if (tail instanceof Functor2 && tail._name == Atom.DOT) {
112 | result += head + ", ";
113 | listPair = tail;
114 | // Loop again.
115 | }
116 | else {
117 | // The list is not terminated with NIL.
118 | result += head + "|" + tail;
119 | break;
120 | }
121 | }
122 |
123 | result += "]";
124 | return result;
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/source/javascript/Functor3.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | function Functor3(name, arg1, arg2, arg3) {
32 | if (name instanceof Atom)
33 | this._name = name;
34 | else
35 | // Assume name is a string.
36 | this._name = Atom.a(name);
37 | this._arg1 = arg1;
38 | this._arg2 = arg2;
39 | this._arg3 = arg3;
40 | }
41 |
42 | // If arg is another Functor3, then succeed (yield once) if this and arg have the
43 | // same name and all functor args unify, otherwise fail (don't yield).
44 | // If arg is a Variable, then call its unify to unify with this.
45 | // Otherwise fail (don't yield).
46 | Functor3.prototype.unify = function(arg) {
47 | arg = YP.getValue(arg);
48 | if (arg instanceof Functor3)
49 | {
50 | if (this._name.equals(arg._name)) {
51 | for each (var l1 in YP.unify(this._arg1, arg._arg1)) {
52 | for each (var l1 in YP.unify(this._arg2, arg._arg2)) {
53 | for each (var l1 in YP.unify(this._arg3, arg._arg3))
54 | yield false;
55 | }
56 | }
57 | }
58 | }
59 | else if (arg instanceof Variable) {
60 | for each (var l1 in arg.unify(this))
61 | yield false;
62 | }
63 | }
64 |
65 | Functor3.prototype.toString = function() {
66 | return this._name + "(" + YP.getValue(this._arg1) + ", " + YP.getValue(this._arg2) + ", " +
67 | YP.getValue(this._arg3) + ")";
68 | }
69 |
70 | Functor3.prototype.termEqual = function(term) {
71 | term = YP.getValue(term);
72 | if (term instanceof Functor3)
73 | return this._name.equals(term._name) && YP.termEqual(this._arg1, term._arg1) &&
74 | YP.termEqual(this._arg2, term._arg2) && YP.termEqual(this._arg3, term._arg3);
75 | return false;
76 | }
77 |
78 | Functor3.prototype.lessThan = function(functor) {
79 | // Do the equal check first since it is faster.
80 | if (!this._name.equals(functor._name))
81 | return this._name.lessThan(functor._name);
82 |
83 | if (!YP.termEqual(this._arg1, functor._arg1))
84 | return YP.termLessThan(this._arg1, functor._arg1);
85 |
86 | if (!YP.termEqual(this._arg2, functor._arg2))
87 | return YP.termLessThan(this._arg2, functor._arg2);
88 |
89 | return YP.termLessThan(this._arg3, functor._arg3);
90 | }
91 |
92 | Functor3.prototype.ground = function() {
93 | return YP.ground(this._arg1) && YP.ground(this._arg2) && YP.ground(this._arg3);
94 | }
95 |
96 | Functor3.prototype.addUniqueVariables = function(variableSet) {
97 | YP.addUniqueVariables(this._arg1, variableSet);
98 | YP.addUniqueVariables(this._arg2, variableSet);
99 | YP.addUniqueVariables(this._arg3, variableSet);
100 | }
101 |
102 | Functor3.prototype.makeCopy = function(copyStore) {
103 | return new Functor3(this._name, YP.makeCopy(this._arg1, copyStore),
104 | YP.makeCopy(this._arg2, copyStore), YP.makeCopy(this._arg3, copyStore));
105 | }
106 |
107 |
--------------------------------------------------------------------------------
/source/javascript/ListPair.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | function ListPair(head, tail) {
32 | Functor2.call(this, Atom.DOT, head, tail);
33 | }
34 |
35 | ListPair.prototype = new Functor2;
36 |
37 | ListPair.make = function(arg1, arg2, arg3) {
38 | if (arg3 !== undefined)
39 | return new ListPair(arg1, new ListPair(arg2, new ListPair(arg3, Atom.NIL)));
40 | if (arg2 !== undefined)
41 | return new ListPair(arg1, new ListPair(arg2, Atom.NIL));
42 |
43 | if (arg1 instanceof Array) {
44 | if (arg1.length <= 0)
45 | return Atom.NIL;
46 |
47 | var result = Atom.NIL;
48 | // Start from the end.
49 | for (var i = arg1.length - 1; i >= 0; --i)
50 | result = new ListPair(arg1[i], result);
51 | return result;
52 | }
53 | else
54 | return new ListPair(arg1, Atom.NIL);
55 | }
56 |
57 | // Return a ListPair version of array, where repeated elements (according to YP.termEqual) are removed.
58 | ListPair.makeWithoutRepeatedTerms = function(array) {
59 | if (array.length <= 0)
60 | return Atom.NIL;
61 |
62 | // Start from the end.
63 | var previousTerm = array[array.length - 1];
64 | var result = new ListPair(previousTerm, Atom.NIL);
65 | for (var i = array.length - 2; i >= 0; --i) {
66 | var term = array[i];
67 | if (YP.termEqual(term, previousTerm))
68 | continue;
69 | result = new ListPair(term, result);
70 | previousTerm = term;
71 | }
72 | return result;
73 | }
74 |
75 | // Return an array of the elements in list or null if it is not
76 | // a proper list. If list is Atom.NIL, return an array of zero elements.
77 | // If the list or one of the tails of the list is Variable, raise an instantiation_error.
78 | // This does not call YP.getValue on each element.
79 | ListPair.toArray = function(list) {
80 | list = YP.getValue(list);
81 | if (list == Atom.NIL)
82 | return [];
83 |
84 | var result = [];
85 | var element = list;
86 | while(true) {
87 | if (element == Atom.NIL)
88 | break;
89 | if (element instanceof Variable)
90 | throw new PrologException(Atom.a("instantiation_error"),
91 | "List tail is an unbound variable");
92 | if (!((element instanceof Functor2) && element._name == Atom.DOT))
93 | // Not a proper list.
94 | return null;
95 | result.push(element._arg1);
96 | element = YP.getValue(element._arg2)
97 | }
98 |
99 | if (result.length <= 0)
100 | return null;
101 | return result;
102 | }
103 |
--------------------------------------------------------------------------------
/source/javascript/PrologException.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | // A PrologException is used as the exception thrown by YP.throw(Term).
32 | // One argument: Create a PrologException with the given arg1 term. The printable exception message is
33 | // the full Term.
34 | // Two arguments: Create a PrologException where the Term is error(arg1, arg2). If arg2 is a string, this
35 | // converts it to an Atom so that Prolog code can use it.
36 | // This uses YP.makeCopy to copy the arguments so that they are valid after unbinding.
37 | function PrologException(arg1, arg2) {
38 | if (arg2 !== undefined) {
39 | arg2 = YP.getValue(arg2);
40 | this._message = arg2.toString();
41 | if (typeof(arg2) == 'string')
42 | arg2 = Atom.a(arg2);
43 | this._term = YP.makeCopy(new Functor2(Atom.a("error"), arg1, arg2), new Variable.CopyStore());
44 | }
45 | else if (arg1 !== undefined) {
46 | this._message = YP.getValue(arg1).toString();
47 | this._term = YP.makeCopy(arg1, new Variable.CopyStore());
48 | }
49 | }
50 |
51 | PrologException.prototype.toString = function() {
52 | return this._message;
53 | }
54 |
55 | PrologException.TypeErrorInfo = function(Type, Culprit, Message) {
56 | this._Type = Type;
57 | this._Culprit = Culprit;
58 | this._Message = Message;
59 | }
60 |
61 | // Return the TypeErrorInfo for this exception, or null if _term does not match
62 | // error(type_error(Type, Culprit), Message).
63 | PrologException.prototype.getTypeErrorInfo = function() {
64 | if (!(this._term instanceof Functor2 && this._term._name._name == "error"))
65 | return null;
66 | var errorTerm = this._term._arg1;
67 | if (!(errorTerm instanceof Functor2 && errorTerm._name._name == "type_error"))
68 | return null;
69 | if (!(errorTerm._arg1 instanceof Atom))
70 | return null;
71 | return new PrologException.TypeErrorInfo(errorTerm._arg1, errorTerm._arg2, this._term._arg2);
72 | }
73 |
74 | PrologException.ExistenceErrorInfo = function(Type, Culprit, Message) {
75 | this._Type = Type;
76 | this._Culprit = Culprit;
77 | this._Message = Message;
78 | }
79 |
80 | // If _Type is procedure and _Culprit is name/artity, return the name. Otherwise return null.
81 | PrologException.ExistenceErrorInfo.prototype.getProcedureName = function() {
82 | if (!(this._Type._name == "procedure" &&
83 | this._Culprit instanceof Functor2 && this._Culprit._name == Atom.SLASH))
84 | return null;
85 | return this._Culprit._arg1;
86 | }
87 |
88 | // If _Type is procedure and _Culprit is name/arity and arity is an integer, return the arity.
89 | // Otherwise return -1.
90 | PrologException.ExistenceErrorInfo.prototype.getProcedureArity = function() {
91 | if (!(this._Type._name == "procedure" &&
92 | this._Culprit instanceof Functor2 && this._Culprit._name == Atom.SLASH))
93 | return -1;
94 | if (typeof(this._Culprit._arg2) != "number")
95 | return -1;
96 | return this._Culprit._arg2;
97 | }
98 |
99 | // Return the ExistenceErrorInfo for this exception, or null if _term does not match
100 | // error(existence_error(Type, Culprit), Message). If the returned ExistenceErrorInfo _Culprit is
101 | // procedure, you can use its getProcedureName and getProcedureArity.
102 | PrologException.prototype.getExistenceErrorInfo = function() {
103 | if (!(this._term instanceof Functor2 && this._term._name._name == "error"))
104 | return null;
105 | var errorTerm = this._term._arg1;
106 | if (!(errorTerm instanceof Functor2 && errorTerm._name._name == "existence_error"))
107 | return null;
108 | if (!(errorTerm._arg1 instanceof Atom))
109 | return null;
110 | return new PrologException.ExistenceErrorInfo(errorTerm._arg1, errorTerm._arg2, this._term._arg2);
111 | }
112 |
--------------------------------------------------------------------------------
/source/javascript/Variable.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | function Variable() {
32 | // Use _isBound separate from _value so that it can be bound to any value,
33 | // including null.
34 | this._isBound = false;
35 | }
36 |
37 | // If this Variable is unbound, then just return this Variable.
38 | // Otherwise, if this has been bound to a value with unify, return the value.
39 | // If the bound value is another Variable, this follows the "variable chain"
40 | // to the end and returns the final value, or the final Variable if it is unbound.
41 | // For more details, see http://yieldprolog.sourceforge.net/tutorial1.html
42 | Variable.prototype.getValue = function() {
43 | if (!this._isBound)
44 | return this;
45 |
46 | var result = this._value;
47 | while (result instanceof Variable) {
48 | if (!result._isBound)
49 | return result;
50 |
51 | // Keep following the Variable chain.
52 | result = result._value;
53 | }
54 |
55 | return result;
56 | }
57 |
58 | // If this Variable is bound, then just call YP.unify to unify this with arg.
59 | // (Note that if arg is an unbound Variable, then YP.unify will bind it to
60 | // this Variable's value.)
61 | // Otherwise, bind this Variable to YP.getValue(arg) and yield once. After the
62 | // yield, return this Variable to the unbound state.
63 | // For more details, see http://yieldprolog.sourceforge.net/tutorial1.html
64 | Variable.prototype.unify = function(arg) {
65 | if (!this._isBound) {
66 | this._value = YP.getValue(arg);
67 | if (this._value == this)
68 | // We are unifying this unbound variable with itself, so leave it unbound.
69 | yield false;
70 | else {
71 | this._isBound = true;
72 | try {
73 | yield false;
74 | } finally {
75 | // Remove the binding.
76 | this._isBound = false;
77 | }
78 | }
79 | }
80 | else {
81 | for each (var l1 in YP.unify(this, arg))
82 | yield false;
83 | }
84 | }
85 |
86 | Variable.prototype.toString = function() {
87 | var value = this.getValue();
88 | if (value === this)
89 | return "_Variable";
90 | else
91 | return value.toString();
92 | }
93 |
94 | // If bound, call YP.addUniqueVariables on the value. Otherwise, if this unbound
95 | // variable is not already in variableSet, add it.
96 | Variable.prototype.addUniqueVariables = function(variableSet) {
97 | if (this._isBound)
98 | YP.addUniqueVariables(this.getValue(), variableSet);
99 | else {
100 | if (variableSet.indexOf(this) < 0)
101 | variableSet.push(this);
102 | }
103 | }
104 |
105 | // If bound, return YP.makeCopy for the value, else return copyStore.getCopy(this).
106 | // However, if copyStore is null, just return this.
107 | Variable.prototype.makeCopy = function(copyStore) {
108 | if (this._isBound)
109 | return YP.makeCopy(this.getValue(), copyStore);
110 | else
111 | return copyStore == null ? this : copyStore.getCopy(this);
112 | }
113 |
114 | Variable.prototype.termEqual = function(term) {
115 | if (this._isBound)
116 | return YP.termEqual(this.getValue(), term);
117 | else
118 | return this === YP.getValue(term);
119 | }
120 |
121 | Variable.prototype.ground = function() {
122 | if (this._isBound)
123 | // This is usually called by YP.ground which already did getValue, so this
124 | // should never be reached, but check anyway.
125 | return YP.ground(this.getValue());
126 | else
127 | return false;
128 | }
129 |
130 | // A CopyStore is used by makeCopy to track which Variable objects have
131 | // been copied.
132 | Variable.CopyStore = function() {
133 | this._inVariableList = []
134 | this._outVariableList = []
135 | }
136 |
137 | // If inVariable has already been copied, return its copy. Otherwise,
138 | // return a fresh Variable associated with inVariable.
139 | Variable.CopyStore.prototype.getCopy = function(inVariable) {
140 | var index = this._inVariableList.indexOf(inVariable);
141 | if (index >= 0)
142 | return this._outVariableList[index];
143 | else {
144 | var outVariable = new Variable();
145 | this._inVariableList.push(inVariable);
146 | this._outVariableList.push(outVariable);
147 | return outVariable;
148 | }
149 | }
150 |
151 | // Return the number of unique variables that have been copied.
152 | Variable.CopyStore.prototype.getNUniqueVariables = function() {
153 | return this._inVariableList.length;
154 | }
155 |
--------------------------------------------------------------------------------
/source/javascript/endComment.js:
--------------------------------------------------------------------------------
1 | */
2 |
--------------------------------------------------------------------------------
/source/javascript/examples/Benchmarks/isoTestSuite.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/source/javascript/examples/Benchmarks/naiveQueens.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/source/javascript/examples/Benchmarks/naiveQueens.js:
--------------------------------------------------------------------------------
1 | function main() {
2 | var startTime = new Date().getTime();
3 | var nAnswers = 0;
4 | var Qs = new Variable();
5 | for each (var l1 in queens(11, Qs))
6 | nAnswers += 1;
7 | var finishTime = new Date().getTime();
8 | document.write("Naive queens: " +
9 | (finishTime - startTime) / 1000.0 + " seconds, " +
10 | nAnswers + " answers ");
11 | }
12 |
13 | function queens(N, Qs) {
14 | var Ns = new Variable();
15 | for each (var l1 in rangeList(1, N, Ns)) {
16 | for each (var l2 in queens3(Ns, Atom.NIL, Qs))
17 | yield false;
18 | }
19 | }
20 |
21 | function queens3(UnplacedQs, SafeQs, Qs) {
22 | var UnplacedQs1 = new Variable();
23 | var Q = new Variable();
24 | for each (var l1 in selectq(Q, UnplacedQs, UnplacedQs1)) {
25 | for each (var l2 in notHasAttack(Q, SafeQs)) {
26 | for each (var l3 in queens3(UnplacedQs1, new ListPair(Q, SafeQs), Qs))
27 | yield false;
28 | }
29 | }
30 | for each (var l1 in YP.unify(UnplacedQs, Atom.NIL)) {
31 | for each (var l2 in YP.unify(Qs, SafeQs))
32 | yield false;
33 | }
34 | }
35 |
36 | function notHasAttack(X, Xs) {
37 | for each (var l1 in attack(X, Xs))
38 | return;
39 |
40 | yield false;
41 | }
42 |
43 | function attack(X, Xs) {
44 | for each (var l1 in attack3(X, 1, Xs))
45 | yield false;
46 | }
47 |
48 | function attack3(X, N, Arg3) {
49 | var Y = new Variable();
50 | for each (var l1 in new ListPair(Y, new Variable()).unify(Arg3)) {
51 | if (YP.getValue(X) == Y.getValue() + YP.getValue(N))
52 | yield false;
53 | if (YP.getValue(X) == Y.getValue() - YP.getValue(N))
54 | yield false;
55 | }
56 |
57 | var Ys = new Variable();
58 | var N1 = new Variable();
59 | for each (var l1 in new ListPair(new Variable(), Ys).unify(Arg3)) {
60 | for each (var l2 in N1.unify(YP.getValue(N) + 1)) {
61 | for each (var l3 in attack3(X, N1, Ys))
62 | yield false;
63 | }
64 | }
65 | }
66 |
67 | function rangeList(M, N, List) {
68 | if (YP.getValue(M) >= YP.getValue(N)) {
69 | for each (var l1 in YP.unify(List, new ListPair(N, Atom.NIL)))
70 | yield false;
71 | }
72 | else {
73 | var Tail = new Variable();
74 | for each (var l1 in rangeList(YP.getValue(M) + 1, YP.getValue(N), Tail)) {
75 | for each (var l2 in YP.unify(List, new ListPair(M, Tail)))
76 | yield false;
77 | }
78 | }
79 | }
80 |
81 | function selectq(X, Arg2, Arg3) {
82 | for each (var l1 in new ListPair(X, Arg3).unify(Arg2))
83 | yield false;
84 |
85 | var Y = new Variable();
86 | var Ys = new Variable();
87 | var Zs = new Variable();
88 | for each (var l1 in new ListPair(Y, Ys).unify(Arg2)) {
89 | for each (var l2 in new ListPair(Y, Zs).unify(Arg3)) {
90 | for each (var l3 in selectq(X, Ys, Zs))
91 | yield false;
92 | }
93 | }
94 | }
95 |
96 | main()
97 |
--------------------------------------------------------------------------------
/source/javascript/examples/Benchmarks/queens.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/source/javascript/examples/Benchmarks/queens.js:
--------------------------------------------------------------------------------
1 | function main() {
2 | var startTime = new Date().getTime();
3 | var nAnswers = 0;
4 | var Qs = new Variable();
5 | for each (var l1 in queens(11, Qs))
6 | nAnswers += 1;
7 | var finishTime = new Date().getTime();
8 | document.write("Optimized queens: " +
9 | (finishTime - startTime) / 1000.0 + " seconds, " +
10 | nAnswers + " answers ");
11 | }
12 |
13 | function queens(N, Qs) {
14 | var Ns = new Variable();
15 | for each (var l1 in rangeList(1, N, Ns)) {
16 | for each (var l2 in queens3(Ns, Atom.NIL, Qs))
17 | yield false;
18 | }
19 | }
20 |
21 | function queens3(UnplacedQs, SafeQs, Qs) {
22 | var UnplacedQsListPair = YP.getValue(UnplacedQs);
23 | if (UnplacedQsListPair instanceof ListPair) {
24 | var UnplacedQs1 = new Variable();
25 | var Q = new Variable();
26 | for each (var l1 in selectq(Q, UnplacedQsListPair, UnplacedQs1)) {
27 | if (!((SafeQs instanceof ListPair) && hasAttack(Q.getValue(), SafeQs))) {
28 | for each (var l2 in queens3(UnplacedQs1, new ListPair(Q, SafeQs), Qs))
29 | yield false;
30 | }
31 | }
32 | }
33 | else {
34 | for each (var l1 in Qs.unify(SafeQs))
35 | yield false;
36 | }
37 | }
38 |
39 | function hasAttack(X, Xs) {
40 | return hasAttack3(X, 1, Xs);
41 | }
42 |
43 | function hasAttack3(X, N, Arg3) {
44 | if (X == YP.getValue(Arg3._arg1) + N || X == YP.getValue(Arg3._arg1) - N)
45 | return true;
46 | if (Arg3._arg2 instanceof ListPair)
47 | return hasAttack3(X, N + 1, YP.getValue(Arg3._arg2));
48 | else
49 | return false;
50 | }
51 |
52 | function rangeList(M, N, List) {
53 | if (M >= N) {
54 | for each (var l1 in List.unify(new ListPair(N, Atom.NIL)))
55 | yield false;
56 | }
57 | else {
58 | var Tail = new Variable();
59 | for each (var l1 in rangeList(M + 1, N, Tail)) {
60 | for each (var l2 in List.unify(new ListPair(M, Tail)))
61 | yield false;
62 | }
63 | }
64 | }
65 |
66 | function selectq(X, Arg2, Arg3) {
67 | for each (var l1 in X.unify(Arg2._arg1)) {
68 | for each (var l2 in Arg3.unify(Arg2._arg2))
69 | yield false;
70 | }
71 |
72 | var Arg2Tail = YP.getValue(Arg2._arg2);
73 | if (Arg2Tail instanceof ListPair) {
74 | var Zs = new Variable();
75 | for each (var l1 in selectq(X, Arg2Tail, Zs)) {
76 | for each (var l2 in Arg3.unify(new ListPair(Arg2._arg1, Zs)))
77 | yield false;
78 | }
79 | }
80 | }
81 |
82 | main();
83 |
84 |
85 |
--------------------------------------------------------------------------------
/source/javascript/examples/YieldPrologTutorial/tutorial1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/source/javascript/examples/YieldPrologTutorial/tutorial2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/source/javascript/examples/YieldPrologTutorial/tutorial2.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | function main() {
32 | document.write("Find relations: ");
33 | var Brother = new Variable();
34 | for each (var l1 in brother("Hillary", Brother))
35 | document.write("Hillary has brother " +
36 | Brother.getValue() + ". ");
37 |
38 | document.write("Check if it is square: ");
39 | for each (var l1 in squaredRectangle(10, 10))
40 | document.write("10 by 10 rectangle is square. ");
41 |
42 | document.write("Make it square: ");
43 | var Width = new Variable();
44 | var Height = new Variable();
45 | for each (var l1 in Width.unify(10)) {
46 | for each (var l2 in squaredRectangle(Width, Height))
47 | document.write("A square of width " +
48 | Width.getValue() + " has height " +
49 | Height.getValue() + ". ");
50 | }
51 |
52 | document.write("Make it square before we know the width: ");
53 | for each (var l1 in squaredRectangle(Width, Height)) {
54 | for each (var l2 in Width.unify(10))
55 | document.write("A square of width " +
56 | Width.getValue() + " has height " +
57 | Height.getValue() + ". ");
58 | }
59 |
60 | document.write("Get one match: ");
61 | for each (var l1 in anyBrother("Hillary", Brother))
62 | document.write("Hillary has a brother " +
63 | Brother.getValue() + ". ");
64 | for each (var l1 in anyBrother("Bill", Brother))
65 | document.write("Bill has a brother " +
66 | Brother.getValue() + ". ");
67 |
68 | document.write("Use cut for negation: ");
69 | for each (var l1 in noBrother("Hillary"))
70 | document.write("Hillary has no brother. ");
71 | for each (var l1 in noBrother("Chelsea"))
72 | document.write("Chelsea has no brother. ");
73 | }
74 |
75 | function brother(Person, Brother) {
76 | for each (var l1 in YP.unify(Person, "Hillary")) {
77 | for each (var l2 in YP.unify(Brother, "Tony"))
78 | yield false;
79 | for each (var l2 in YP.unify(Brother, "Hugh"))
80 | yield false;
81 | }
82 | for each (var l1 in YP.unify(Person, "Bill")) {
83 | for each (var l2 in YP.unify(Brother, "Roger"))
84 | yield false;
85 | }
86 | }
87 |
88 | function squaredRectangle(Width, Height) {
89 | for each (var l1 in YP.unify(Width, Height))
90 | yield false;
91 | }
92 |
93 | function anyBrother(Person, Brother) {
94 | for each (var l1 in brother(Person, Brother)) {
95 | yield false;
96 | break;
97 | }
98 | }
99 |
100 | function noBrother(Person) {
101 | var Brother = new Variable();
102 | for each (var l1 in brother(Person, Brother))
103 | return;
104 | yield false;
105 | }
106 |
107 | main();
108 |
109 |
110 |
--------------------------------------------------------------------------------
/source/javascript/examples/YieldPrologTutorial/tutorial3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/source/javascript/examples/YieldPrologTutorial/tutorial3.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | function main() {
32 | document.write("Return a list of 2 elements: ");
33 | var List = new Variable();
34 | for each (var l1 in makeList("a", "b", List))
35 | document.write("List = " +
36 | List.getValue() + ". ");
37 |
38 | document.write("Unify two lists: ");
39 | var Second = new Variable();
40 | for each (var l1 in makeList("x", Second,
41 | new ListPair("x", new ListPair("y", Atom.NIL))))
42 | document.write("The second element is " +
43 | Second.getValue() + ". ");
44 | }
45 |
46 | function makeList(First, Second, List) {
47 | var list1 = new ListPair(Second, Atom.NIL);
48 | var result = new ListPair(First, list1);
49 | for each (var l1 in YP.unify(List, result))
50 | yield false;
51 | }
52 |
53 | main();
54 |
55 |
56 |
--------------------------------------------------------------------------------
/source/javascript/examples/YieldPrologTutorial/tutorial4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/source/javascript/examples/YieldPrologTutorial/tutorial4.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 | */
30 |
31 | function main() {
32 | YP.assertFact(Atom.a("brother"),
33 | [Atom.a("Hillary"), Atom.a("Hugh")]);
34 | YP.assertFact(Atom.a("brother"),
35 | [Atom.a("Hillary"), Atom.a("Tony")]);
36 | YP.assertFact(Atom.a("brother"),
37 | [Atom.a("Bill"), Atom.a("Roger")]);
38 |
39 | var Brother = new Variable();
40 | document.write("Using dynamic assert: ");
41 | for each (var l1 in YP.matchDynamic
42 | (Atom.a("brother"),
43 | [Atom.a("Hillary"), Brother]))
44 | document.write("Hillary has brother " +
45 | Brother.getValue() + ". ");
46 |
47 | var prologCode =
48 | "uncle(Person, Uncle) :- \n" +
49 | " parent(Person, Parent), \n" +
50 | " brother(Parent, Uncle). \n";
51 | document.write(" // Compiled code: ");
52 | compileAndWrite(prologCode);
53 |
54 | prologCode =
55 | ":- import('', [parent/2]). \n" +
56 | "uncle(Person, Uncle) :- \n" +
57 | " parent(Person, Parent), \n" +
58 | " brother(Parent, Uncle). \n";
59 | document.write("// Calling an imported function: ");
60 | compileAndWrite(prologCode);
61 |
62 | prologCode =
63 | "parent('Chelsea', 'Hillary'). \n" +
64 | "parent('Chelsea', 'Bill'). \n" +
65 |
66 | "uncle(Person, Uncle) :- \n" +
67 | " parent(Person, Parent), \n" +
68 | " brother(Parent, Uncle). \n";
69 | document.write("// Calling a locally-defined function: ");
70 | compileAndWrite(prologCode);
71 |
72 | prologCode =
73 | ":- import('', [parent/2]). \n" +
74 | "uncle(Person, Uncle) :- \n" +
75 | " Goal = parent(Person, Parent), \n" +
76 | " Goal, \n" +
77 | " brother(Parent, Uncle). \n";
78 | document.write("// Calling a dynamic goal: ");
79 | compileAndWrite(prologCode);
80 |
81 | document.write
82 | ("Calling compiled code having a dynamic goal: ");
83 | var Person = new Variable();
84 | var Uncle = new Variable();
85 | for each (var l1 in uncle(Person, Uncle))
86 | document.write(Person.getValue() +
87 | " has uncle " + Uncle.getValue() + ". ");
88 | }
89 |
90 | function compileAndWrite(prologCode) {
91 | YP.see(new YP.StringReader(prologCode));
92 | var output = new YP.StringWriter();
93 | YP.tell(output);
94 | var TermList = new Variable();
95 | var PseudoCode = new Variable();
96 | for each (var l1 in parseInput(TermList)) {
97 | for each (var l2 in makeFunctionPseudoCode
98 | (TermList, PseudoCode))
99 | convertFunctionJavascript(PseudoCode);
100 | }
101 | YP.seen();
102 | YP.told();
103 | document.write
104 | (output.toString().replace
105 | (/\n/g," ").replace(/ /g," "));
106 | }
107 |
108 | function getDeclaringClass() { return null; }
109 |
110 | function parent(Person, Parent) {
111 | for each (var l2 in YP.unify
112 | (Person, Atom.a("Chelsea"))) {
113 | for each (var l3 in YP.unify
114 | (Parent, Atom.a("Hillary"))) {
115 | yield false;
116 | }
117 | }
118 | for each (var l2 in YP.unify
119 | (Person, Atom.a("Chelsea"))) {
120 | for each (var l3 in YP.unify
121 | (Parent, Atom.a("Bill"))) {
122 | yield false;
123 | }
124 | }
125 | }
126 |
127 | function uncle(Person, Uncle) {
128 | {
129 | var Goal = new Variable();
130 | var Parent = new Variable();
131 | for each (var l2 in YP.unify
132 | (Goal, new Functor2
133 | (Atom.a("parent", Atom.a("")),
134 | Person, Parent))) {
135 | for each (var l3 in YP.getIterator
136 | (Goal, getDeclaringClass())) {
137 | for each (var l4 in YP.matchDynamic
138 | (Atom.a("brother"), [Parent, Uncle])) {
139 | yield false;
140 | }
141 | }
142 | }
143 | }
144 | }
145 |
146 | main();
147 |
148 |
149 |
--------------------------------------------------------------------------------
/source/javascript/makeYieldProlog.bat:
--------------------------------------------------------------------------------
1 | copy /B readme.js + makeYieldProlog.bat + endComment.js + ^
2 | YP.js + ^
3 | Variable.js + ^
4 | Atom.js + ^
5 | Functor1.js + ^
6 | Functor2.js + ^
7 | Functor3.js + ^
8 | Functor.js + ^
9 | ListPair.js + ^
10 | PrologException.js + ^
11 | IndexedAnswers.js + ^
12 | FindallAnswers.js + ^
13 | BagofAnswers.js + ^
14 | Parser.js + ^
15 | Compiler.js ^
16 | YieldProlog.js
17 | rem Copy the result to the web interface and bin.
18 | copy YieldProlog.js ..\..\doc
19 | copy YieldProlog.js ..\..\bin
20 | copy ..\..\doc\queryEditor.html ..\..\bin
21 |
--------------------------------------------------------------------------------
/source/javascript/readme.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2007-2008, Jeff Thompson
3 | *
4 | * All rights reserved.
5 | *
6 | * Redistribution and use in source and binary forms, with or without
7 | * modification, are permitted provided that the following conditions are met:
8 | *
9 | * * Redistributions of source code must retain the above copyright
10 | * notice, this list of conditions and the following disclaimer.
11 | * * Redistributions in binary form must reproduce the above copyright
12 | * notice, this list of conditions and the following disclaimer in the
13 | * documentation and/or other materials provided with the distribution.
14 | * * Neither the name of the copyright holder nor the names of its contributors
15 | * may be used to endorse or promote products derived from this software
16 | * without specific prior written permission.
17 | *
18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 |
30 | This file is a concatenation of all the source files for Yield Prolog so
31 | that you only need to include one file.
32 |
33 | This file was created with the following script (see file "makeYieldProlog.bat"):
34 |
--------------------------------------------------------------------------------
/source/python/Atom.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import StringIO
30 | from YP import *
31 | from Variable import *
32 |
33 | class Atom(IUnifiable):
34 | # You should not call this constructor, but use Atom.a(name) instead.
35 | def __init__(self, name, module = None):
36 | self._name = name
37 | self._module = module
38 |
39 | # Return an Atom object with the name and module. If module is null or Atom.NIL,
40 | # this behaves like Atom.a(name, None) and returns the unique object where the module is None.
41 | # If module is None or Atom.NIL, return a unique Atom object.
42 | # If module is not None or Atom.NIL, this may or may not be the same object as another Atom
43 | # with the same name and module.
44 | # You should use this to create an Atom instead of calling the Atom constructor.
45 | @staticmethod
46 | def a(name, module = None):
47 | if module == None or module == Atom.NIL:
48 | atom = Atom._atomStore.get(name, False)
49 | if atom == False:
50 | atom = Atom(name)
51 | Atom._atomStore[name] = atom
52 | return atom
53 | else:
54 | return Atom(name, module)
55 |
56 | # If Obj is an Atom unify its _module with Module. If the Atom's _module is None, use Atom.NIL.
57 | @staticmethod
58 | def module(Obj, Module):
59 | Obj = YP.getValue(Obj)
60 | if isinstance(Obj, Atom):
61 | if Obj._module == None:
62 | return YP.unify(Module, Atom.NIL)
63 | else:
64 | return YP.unify(Module, Obj._module)
65 |
66 | return YP.fail()
67 |
68 | def unify(self, arg):
69 | arg = YP.getValue(arg)
70 | if isinstance(arg, Atom):
71 | if self.equals(arg):
72 | return YP.succeed()
73 | else:
74 | return YP.fail()
75 | elif isinstance(arg, Variable):
76 | return arg.unify(self)
77 | else:
78 | return YP.fail()
79 |
80 | def addUniqueVariables(self, variableSet):
81 | # Atom does not contain variables.
82 | pass
83 |
84 | def makeCopy(self, copyStore):
85 | # Atom does not contain variables that need to be copied.
86 | return self
87 |
88 | def termEqual(self, term):
89 | return self.equals(YP.getValue(term))
90 |
91 | def ground(self):
92 | # Atom is always ground.
93 | return True
94 |
95 | def equals(self, obj):
96 | if isinstance(obj, Atom):
97 | if self._module == None and obj._module == None:
98 | # When _declaringClass is None, we always use an identical object from _atomStore.
99 | return self == obj
100 | # Otherwise, ignore _declaringClass and do a normal string compare on the _name.
101 | return self._name == obj._name
102 |
103 | return False
104 |
105 | def __str__(self):
106 | return self._name
107 |
108 | def __hash__(self):
109 | return hash(self._name)
110 |
111 | def toQuotedString(self):
112 | if len(self._name) == 0:
113 | return "''"
114 | elif self == Atom.NIL:
115 | return "[]"
116 |
117 | result = StringIO.StringIO()
118 | useQuotes = False
119 | for c in self._name:
120 | cInt = ord(c)
121 | if c == '\'':
122 | result.write("''")
123 | useQuotes = True
124 | elif c == '_' or cInt >= ord('a') and cInt <= ord('z') or \
125 | cInt >= ord('A') and cInt <= ord('Z') or cInt >= ord('0') and cInt <= ord('9'):
126 | result.write(c)
127 | else:
128 | # Debug: Need to handle non-printable chars.
129 | result.write(c)
130 | useQuotes = True
131 |
132 | if not useQuotes and ord(self._name[0]) >= ord('a') and ord(self._name[0]) <= ord('z'):
133 | return result.getvalue()
134 | else:
135 | # Surround in single quotes.
136 | result.write('\'')
137 | return "'" + result.getvalue()
138 |
139 | # Return true if _name is lexicographically less than atom._name.
140 | def lessThan(self, atom):
141 | return self._name < atom._name
142 |
143 | _atomStore = {}
144 |
145 | # We will set these below after Atom is defined
146 | NIL = None
147 | DOT = None
148 | F = None
149 | SLASH = None
150 | HAT = None
151 | RULE = None
152 | TRUE = None
153 |
154 | Atom.NIL = Atom.a("[]")
155 | Atom.DOT = Atom.a(".")
156 | Atom.F = Atom.a("f")
157 | Atom.SLASH = Atom.a("/")
158 | Atom.HAT = Atom.a("^")
159 | Atom.RULE = Atom.a(":-")
160 | Atom.TRUE = Atom.a("true")
161 |
--------------------------------------------------------------------------------
/source/python/FindallAnswers.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from YP import *
30 | from ListPair import *
31 | from Variable import *
32 |
33 | # A FindallAnswers holds answers for findall.
34 | class FindallAnswers(object):
35 | def __init__(self, Template):
36 | self._template = Template;
37 | self._bagArray = [];
38 |
39 | def add(self):
40 | self._bagArray.append(YP.makeCopy(self._template, Variable.CopyStore()))
41 |
42 | def resultArray(self):
43 | return self._bagArray
44 |
45 | # Unify Bag with the result. This frees the internal answers, so you can only call this once.
46 | def result(self, Bag):
47 | value = ListPair.make(self._bagArray)
48 | # Try to free the memory.
49 | self._bagArray = None
50 | return YP.unify(Bag, value)
51 |
52 | # This is a simplified findall when the goal is a single call.
53 | @staticmethod
54 | def findall(Template, goal, Bag):
55 | findallAnswers = FindallAnswers(Template)
56 | for l1 in goal:
57 | findallAnswers.add()
58 | return findallAnswers.result(Bag)
59 |
60 | # Like findall, except return an array of the results.
61 | @staticmethod
62 | def findallArray(Template, goal):
63 | findallAnswers = FindallAnswers(Template)
64 | for l1 in goal:
65 | findallAnswers.add()
66 | return findallAnswers.resultArray()
67 |
68 |
--------------------------------------------------------------------------------
/source/python/Functor.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from YP import *
30 | from Atom import *
31 | from Functor1 import *
32 | from Functor2 import *
33 | from Functor3 import *
34 | from Variable import *
35 |
36 | class Functor(IUnifiable):
37 | def __init__(self, name, args):
38 | if len(args) <= 3:
39 | if len(args) == 0:
40 | raise Exception("For arity 0 functor, just use name as an Atom")
41 | elif len(args) == 1:
42 | raise Exception("For arity 1 functor, use Functor1")
43 | elif len(args) == 2:
44 | raise Exception("For arity 2 functor, use Functor2")
45 | elif len(args) == 3:
46 | raise Exception("For arity 3 functor, use Functor3")
47 | else:
48 | # (This shouldn't happen, but include it for completeness.
49 | raise Exception("Cannot create a Functor of arity " + str(len(args)))
50 |
51 | if isinstance(name, Atom):
52 | self._name = name
53 | else:
54 | # Assume name is a string.
55 | self._name = Atom.a(name)
56 | self._args = args
57 |
58 |
59 | # Return an Atom, Functor1, Functor2, Functor3 or Functor depending on the
60 | # length of args.
61 | # Note that this is different than the Functor constructor which requires
62 | # the length of args to be greater than 3.
63 | @staticmethod
64 | def make(name, args):
65 | if not isinstance(name, Atom):
66 | # Assume name is a string.
67 | name = Atom.a(name)
68 |
69 | if len(args) <= 0:
70 | return name
71 | elif len(args) == 1:
72 | return Functor1(name, args[0])
73 | elif len(args) == 2:
74 | return Functor2(name, args[0], args[1])
75 | elif len(args) == 3:
76 | return Functor3(name, args[0], args[1], args[2])
77 | else:
78 | return Functor(name, args)
79 |
80 | # If arg is another Functor, then succeed (yield once) if this and arg have the
81 | # same name and all functor args unify, otherwise fail (don't yield).
82 | # If arg is a Variable, then call its unify to unify with this.
83 | # Otherwise fail (don't yield).
84 | def unify(self, arg):
85 | arg = YP.getValue(arg)
86 | if isinstance(arg, Functor):
87 | if self._name.equals(arg._name):
88 | return YP.unifyArrays(self._args, arg._args)
89 | else:
90 | return YP.fail()
91 | elif isinstance(arg, Variable):
92 | return arg.unify(self)
93 | else:
94 | return YP.fail()
95 |
96 | def __str__(self):
97 | result = str(self._name) + "(" + str(YP.getValue(self._args[0]))
98 | for i in range(1, len(self._args)):
99 | result += ", " + str(YP.getValue(self._args[i]))
100 | result += ")"
101 | return result
102 |
103 | def termEqual(self, term):
104 | term = YP.getValue(term)
105 | if isinstance(term, Functor1):
106 | if self._name.equals(term._name) and len(self._args) == len(term._arg):
107 | for i in range(0, len(self._args)):
108 | if not YP.termEqual(self._args[i], term._args[i]):
109 | return False
110 | return True
111 | return False
112 |
113 | def lessThan(self, functor):
114 | # Do the equal check first since it is faster.
115 | if not self._name.equals(functor._name):
116 | return _name.lessThan(functor._name)
117 |
118 | if len(self._args) != len(functor._args):
119 | return len(self._args) < len(functor._args)
120 |
121 | for i in range(0, len(self._args)):
122 | if not YP.termEqual(self._args[i], functor._args[i]):
123 | return YP.termLessThan(self._args[i], functor._args[i])
124 | return False
125 |
126 | def ground(self):
127 | for i in range(0, len(self._args)):
128 | if not YP.ground(self._args[i]):
129 | return False
130 | return True
131 |
132 | def addUniqueVariables(self, variableSet):
133 | for i in range(0, len(self._args)):
134 | YP.addUniqueVariables(self._args[i], variableSet)
135 |
136 | def makeCopy(self, copyStore):
137 | argsCopy = [YP.makeCopy(arg, copyStore) for arg in self._args]
138 | return Functor(self._name, argsCopy)
139 |
--------------------------------------------------------------------------------
/source/python/Functor1.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from YP import *
30 | from Variable import *
31 | from Atom import *
32 |
33 | class Functor1(IUnifiable):
34 | def __init__(self, name, arg1):
35 | if isinstance(name, Atom):
36 | self._name = name
37 | else:
38 | self._name = Atom.a(name)
39 | self._arg1 = arg1
40 |
41 | # If arg is another Functor1, then succeed (yield once) if this and arg have the
42 | # same name and the functor args unify, otherwise fail (don't yield).
43 | # If arg is a Variable, then call its unify to unify with this.
44 | # Otherwise fail (don't yield).
45 | def unify(self, arg):
46 | arg = YP.getValue(arg)
47 | if isinstance(arg, Functor1):
48 | if self._name.equals(arg._name):
49 | for l1 in YP.unify(self._arg1, arg._arg1):
50 | yield False
51 | elif isinstance(arg, Variable):
52 | for l1 in arg.unify(self):
53 | yield False
54 |
55 | def __str__(self):
56 | return str(self._name) + "(" + str(YP.getValue(self._arg1)) + ")"
57 |
58 | def termEqual(self, term):
59 | term = YP.getValue(term)
60 | if isinstance(term, Functor1):
61 | return self._name.equals(term._name) and YP.termEqual(self._arg1, term._arg1)
62 | return False
63 |
64 | def lessThan(self, functor):
65 | # Do the equal check first since it is faster.
66 | if not self._name.equals(functor._name):
67 | return self._name.lessThan(functor._name)
68 |
69 | return YP.termLessThan(self._arg1, functor._arg1)
70 |
71 | def ground(self):
72 | return YP.ground(self._arg1)
73 |
74 | def addUniqueVariables(self, variableSet):
75 | YP.addUniqueVariables(self._arg1, variableSet)
76 |
77 | def makeCopy(self, copyStore):
78 | return Functor1(self._name, YP.makeCopy(self._arg1, copyStore))
79 |
--------------------------------------------------------------------------------
/source/python/Functor2.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from YP import *
30 | from Variable import *
31 | from Atom import *
32 |
33 | class Functor2(IUnifiable):
34 | def __init__(self, name, arg1, arg2):
35 | if isinstance(name, Atom):
36 | self._name = name
37 | else:
38 | self._name = Atom.a(name)
39 | self._arg1 = arg1
40 | self._arg2 = arg2
41 |
42 | # If arg is another Functor2, then succeed (yield once) if this and arg have the
43 | # same name and all functor args unify, otherwise fail (don't yield).
44 | # If arg is a Variable, then call its unify to unify with this.
45 | # Otherwise fail (don't yield).
46 | def unify(self, arg):
47 | arg = YP.getValue(arg)
48 | if isinstance(arg, Functor2):
49 | if self._name.equals(arg._name):
50 | for l1 in YP.unify(self._arg1, arg._arg1):
51 | for l2 in YP.unify(self._arg2, arg._arg2):
52 | yield False
53 | elif isinstance(arg, Variable):
54 | for l1 in arg.unify(self):
55 | yield False
56 |
57 | def __str__(self):
58 | if self._name == Atom.DOT:
59 | return Functor2.listPairToString(self)
60 | else:
61 | return str(self._name) + "(" + str(YP.getValue(self._arg1)) + ", " + \
62 | str(YP.getValue(self._arg2)) + ")"
63 |
64 | def termEqual(self, term):
65 | term = YP.getValue(term)
66 | if isinstance(term, Functor2):
67 | return self._name.equals(term._name) and YP.termEqual(self._arg1, term._arg1) \
68 | and YP.termEqual(self._arg2, term._arg2)
69 | return False
70 |
71 | def lessThan(self, functor):
72 | # Do the equal check first since it is faster.
73 | if not self._name.equals(functor._name):
74 | return self._name.lessThan(functor._name)
75 |
76 | if not YP.termEqual(self._arg1, functor._arg1):
77 | return YP.termLessThan(self._arg1, functor._arg1)
78 |
79 | return YP.termLessThan(self._arg2, functor._arg2)
80 |
81 | def ground(self):
82 | return YP.ground(self._arg1) and YP.ground(self._arg2)
83 |
84 | def addUniqueVariables(self, variableSet):
85 | YP.addUniqueVariables(self._arg1, variableSet)
86 | YP.addUniqueVariables(self._arg2, variableSet)
87 |
88 | def makeCopy(self, copyStore):
89 | return Functor2(self._name, YP.makeCopy(self._arg1, copyStore), \
90 | YP.makeCopy(self._arg2, copyStore))
91 |
92 | @staticmethod
93 | def listPairToString(listPair):
94 | result = "["
95 | while True:
96 | head = YP.getValue(listPair._arg1)
97 | tail = YP.getValue(listPair._arg2)
98 | if tail == Atom.NIL:
99 | result += str(head)
100 | break
101 | elif isinstance(tail, Functor2) and tail._name == Atom.DOT:
102 | result += str(head) + ", "
103 | listPair = tail
104 | # Loop again.
105 | else:
106 | # The list is not terminated with NIL.
107 | result += str(head) + "|" + str(tail)
108 | break
109 |
110 | result += "]"
111 | return result
112 |
--------------------------------------------------------------------------------
/source/python/Functor3.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from YP import *
30 | from Variable import *
31 | from Atom import *
32 |
33 | class Functor3(IUnifiable):
34 | def __init__(self, name, arg1, arg2, arg3):
35 | if isinstance(name, Atom):
36 | self._name = name
37 | else:
38 | self._name = Atom.a(name)
39 | self._arg1 = arg1
40 | self._arg2 = arg2
41 | self._arg3 = arg3
42 |
43 | # If arg is another Functor3, then succeed (yield once) if this and arg have the
44 | # same name and all functor args unify, otherwise fail (don't yield).
45 | # If arg is a Variable, then call its unify to unify with this.
46 | # Otherwise fail (don't yield).
47 | def unify(self, arg):
48 | arg = YP.getValue(arg)
49 | if isinstance(arg, Functor3):
50 | if self._name.equals(arg._name):
51 | for l1 in YP.unify(self._arg1, arg._arg1):
52 | for l2 in YP.unify(self._arg2, arg._arg2):
53 | for l3 in YP.unify(self._arg3, arg._arg3):
54 | yield False
55 | elif isinstance(arg, Variable):
56 | for l1 in arg.unify(self):
57 | yield False
58 |
59 | def __str__(self):
60 | return str(self._name) + "(" + str(YP.getValue(self._arg1)) + ", " + \
61 | str(YP.getValue(self._arg2)) + ", " + str(YP.getValue(self._arg3)) + ")"
62 |
63 | def termEqual(self, term):
64 | term = YP.getValue(term)
65 | if isinstance(term, Functor3):
66 | return self._name.equals(term._name) and YP.termEqual(self._arg1, term._arg1) \
67 | and YP.termEqual(self._arg2, term._arg2) \
68 | and YP.termEqual(self._arg3, term._arg3)
69 | return False
70 |
71 | def lessThan(self, functor):
72 | # Do the equal check first since it is faster.
73 | if not self._name.equals(functor._name):
74 | return self._name.lessThan(functor._name)
75 |
76 | if not YP.termEqual(self._arg1, functor._arg1):
77 | return YP.termLessThan(self._arg1, functor._arg1)
78 |
79 | if not YP.termEqual(self._arg2, functor._arg2):
80 | return YP.termLessThan(self._arg2, functor._arg2)
81 |
82 | return YP.termLessThan(self._arg3, functor._arg3)
83 |
84 | def ground(self):
85 | return YP.ground(self._arg1) and YP.ground(self._arg2) and YP.ground(self._arg3)
86 |
87 | def addUniqueVariables(self, variableSet):
88 | YP.addUniqueVariables(self._arg1, variableSet)
89 | YP.addUniqueVariables(self._arg2, variableSet)
90 | YP.addUniqueVariables(self._arg3, variableSet)
91 |
92 | def makeCopy(self, copyStore):
93 | return Functor3(self._name, YP.makeCopy(self._arg1, copyStore), \
94 | YP.makeCopy(self._arg2, copyStore), \
95 | YP.makeCopy(self._arg3, copyStore))
96 |
--------------------------------------------------------------------------------
/source/python/ListPair.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from YP import *
30 | from Functor2 import *
31 |
32 | class ListPair(Functor2):
33 | def __init__(self, head, tail):
34 | Functor2.__init__(self, Atom.DOT, head, tail)
35 |
36 | @staticmethod
37 | def make(arg1, arg2 = None, arg3 = None):
38 | if arg3 != None:
39 | return ListPair(arg1, ListPair(arg2, ListPair(arg3, Atom.NIL)))
40 | if arg2 != None:
41 | return ListPair(arg1, ListPair(arg2, Atom.NIL))
42 |
43 | if isinstance(arg1, list):
44 | if len(arg1) <= 0:
45 | return Atom.NIL
46 |
47 | result = Atom.NIL
48 | # Start from the end.
49 | for i in range(len(arg1) - 1, -1, -1):
50 | result = ListPair(arg1[i], result)
51 | return result
52 | else:
53 | return ListPair(arg1, Atom.NIL)
54 |
55 | # Return a ListPair version of array, where repeated elements (according to YP.termEqual) are removed.
56 | @staticmethod
57 | def makeWithoutRepeatedTerms(array):
58 | if len(array) <= 0:
59 | return Atom.NIL
60 |
61 | # Start from the end.
62 | previousTerm = array[len(array) - 1]
63 | result = ListPair(previousTerm, Atom.NIL)
64 | for i in range(len(array) - 2, -1, -1):
65 | term = array[i]
66 | if YP.termEqual(term, previousTerm):
67 | continue
68 | result = ListPair(term, result)
69 | previousTerm = term
70 |
71 | return result
72 |
73 | # Return an array of the elements in list or null if it is not
74 | # a proper list. If list is Atom.NIL, return an array of zero elements.
75 | # If the list or one of the tails of the list is Variable, raise an instantiation_error.
76 | # This does not call YP.getValue on each element.
77 | @staticmethod
78 | def toArray(list):
79 | list = YP.getValue(list)
80 | if list == Atom.NIL:
81 | return []
82 |
83 | result = []
84 | element = list
85 | while True:
86 | if element == Atom.NIL:
87 | break
88 | if isinstance(element, Variable):
89 | raise PrologException(Atom.a("instantiation_error"), "List tail is an unbound variable")
90 | if not (isinstance(element, Functor2) and element._name == Atom.DOT):
91 | # Not a proper list.
92 | return None
93 | result.append(element._arg1)
94 | element = YP.getValue(element._arg2)
95 |
96 | if len(result) <= 0:
97 | return None
98 | return result
99 |
--------------------------------------------------------------------------------
/source/python/PrologException.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from YP import *
30 | from Functor2 import *
31 |
32 | # A PrologException is used as the exception thrown by YP.throw(Term).
33 | # One argument: Create a PrologException with the given arg1 term. The printable exception message is the full Term.
34 | # Two arguments: Create a PrologException where the Term is error(arg1, arg2). If arg2 is a string, this
35 | # converts it to an Atom so that Prolog code can use it.
36 | # This uses YP.makeCopy to copy the arguments so that they are valid after unbinding.
37 | class PrologException(Exception):
38 | def __init__(self, arg1, arg2 = None):
39 | if arg2 != None:
40 | arg2 = YP.getValue(arg2);
41 | Exception.__init__(self, str(arg2))
42 | if isinstance(arg2, str):
43 | arg2 = Atom.a(arg2)
44 | self._term = YP.makeCopy(Functor2(Atom.a("error"), arg1, arg2), Variable.CopyStore())
45 | else:
46 | Exception.__init__(self, str(YP.getValue(arg1)))
47 | self._term = YP.makeCopy(arg1, Variable.CopyStore())
48 |
49 | class TypeErrorInfo(object):
50 | def __init__(self, Type, Culprit, Message):
51 | self._Type = Type
52 | self._Culprit = Culprit
53 | self._Message = Message
54 |
55 | # Return the TypeErrorInfo for this exception, or None if _term does not match
56 | # error(type_error(Type, Culprit), Message).
57 | def getTypeErrorInfo(self):
58 | if not (isinstance(self._term, Functor2) and self._term._name._name == "error"):
59 | return None
60 | errorTerm = self._term._arg1
61 | if not (isinstance(errorTerm, Functor2) and errorTerm._name._name == "type_error"):
62 | return None
63 | if not isinstance(errorTerm._arg1, Atom):
64 | return None
65 | return PrologException.TypeErrorInfo(errorTerm._arg1, errorTerm._arg2, self._term._arg2)
66 |
67 | class ExistenceErrorInfo(object):
68 | def __init__(self, Type, Culprit, Message):
69 | self._Type = Type
70 | self._Culprit = Culprit
71 | self._Message = Message
72 |
73 | # If _Type is procedure and _Culprit is name/artity, return the name. Otherwise return null.
74 | def getProcedureName(self):
75 | if not (self._Type._name == "procedure" and \
76 | isinstance(self._Culprit, Functor2) and self._Culprit._name == Atom.SLASH):
77 | return None
78 | return self._Culprit._arg1
79 |
80 | # If _Type is procedure and _Culprit is name/arity and arity is an integer, return the arity.
81 | # Otherwise return -1.
82 | def getProcedureArity(self):
83 | if not (self._Type._name == "procedure" and \
84 | isinstance(self._Culprit, Functor2) and self._Culprit._name == Atom.SLASH):
85 | return -1
86 | if not isinstance(self._Culprit._arg2, int):
87 | return -1
88 | return self._Culprit._arg2
89 |
90 | # Return the ExistenceErrorInfo for this exception, or None if _term does not match
91 | # error(existence_error(Type, Culprit), Message). If the returned ExistenceErrorInfo _Culprit is
92 | # procedure, you can use its getProcedureName and getProcedureArity.
93 | def getExistenceErrorInfo(self):
94 | if not (isinstance(self._term, Functor2) and self._term._name._name == "error"):
95 | return None
96 | errorTerm = self._term._arg1
97 | if not (isinstance(errorTerm, Functor2) and errorTerm._name._name == "existence_error"):
98 | return None
99 | if not isinstance(errorTerm._arg1, Atom):
100 | return None
101 | return PrologException.ExistenceErrorInfo(errorTerm._arg1, errorTerm._arg2, self._term._arg2)
102 |
--------------------------------------------------------------------------------
/source/python/Variable.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | from YP import *
30 |
31 | class IUnifiable(object):
32 | pass
33 |
34 | class Variable(IUnifiable):
35 | def __init__(self):
36 | # Use _isBound separate from _value so that it can be bound to any value,
37 | # including None.
38 | self._isBound = False
39 |
40 | # If this Variable is unbound, then just return this Variable.
41 | # Otherwise, if this has been bound to a value with unify, return the value.
42 | # If the bound value is another Variable, this follows the "variable chain"
43 | # to the end and returns the final value, or the final Variable if it is unbound.
44 | # For more details, see http://yieldprolog.sourceforge.net/tutorial1.html
45 | def getValue(self):
46 | if not self._isBound:
47 | return self
48 |
49 | result = self._value
50 | while isinstance(result, Variable):
51 | if not result._isBound:
52 | return result
53 |
54 | # Keep following the Variable chain.
55 | result = result._value
56 |
57 | return result
58 |
59 | # If this Variable is bound, then just call YP.unify to unify this with arg.
60 | # (Note that if arg is an unbound Variable, then YP.unify will bind it to
61 | # this Variable's value.)
62 | # Otherwise, bind this Variable to YP.getValue(arg) and yield once. After the
63 | # yield, return this Variable to the unbound state.
64 | # For more details, see http://yieldprolog.sourceforge.net/tutorial1.html
65 | def unify(self, arg):
66 | if not self._isBound:
67 | self._value = YP.getValue(arg)
68 | if self._value == self:
69 | # We are unifying this unbound variable with itself, so leave it unbound.
70 | yield False
71 | else:
72 | self._isBound = True
73 | try:
74 | yield False
75 | finally:
76 | # Remove the binding.
77 | self._isBound = False
78 | else:
79 | for l1 in YP.unify(self, arg):
80 | yield False
81 |
82 | # If bound, call YP.addUniqueVariables on the value. Otherwise, if this unbound
83 | # variable is not already in variableSet, add it.
84 | def addUniqueVariables(self, variableSet):
85 | if self._isBound:
86 | YP.addUniqueVariables(self.getValue(), variableSet)
87 | else:
88 | if variableSet.count(self) == 0:
89 | variableSet.append(self)
90 |
91 | def __str__(self):
92 | value = self.getValue()
93 | if value == self:
94 | return "_Variable"
95 | else:
96 | return value.__str__()
97 |
98 | # If bound, return YP.makeCopy for the value, else return copyStore.getCopy(this).
99 | # However, if copyStore is None, just return this.
100 | def makeCopy(self, copyStore):
101 | if self._isBound:
102 | return YP.makeCopy(self.getValue(), copyStore)
103 | else:
104 | if copyStore == None:
105 | return self
106 | else:
107 | return copyStore.getCopy(self)
108 |
109 | def termEqual(self, term):
110 | if self._isBound:
111 | return YP.termEqual(self.getValue(), term)
112 | else:
113 | return self == YP.getValue(term)
114 |
115 | def ground(self):
116 | if this._isBound:
117 | # This is usually called by YP.ground which already did getValue, so this
118 | # should never be reached, but check anyway.
119 | return YP.ground(self.getValue())
120 | else:
121 | return False
122 |
123 | # A CopyStore is used by makeCopy to track which Variable objects have
124 | # been copied.
125 | class CopyStore(object):
126 | def __init__(self):
127 | self._inVariableList = []
128 | self._outVariableList = []
129 |
130 | # If inVariable has already been copied, return its copy. Otherwise,
131 | # return a fresh Variable associated with inVariable.
132 | def getCopy(self, inVariable):
133 | if self._inVariableList.count(inVariable) > 0:
134 | return self._outVariableList[self._inVariableList.index(inVariable)]
135 | else:
136 | outVariable = Variable()
137 | self._inVariableList.append(inVariable)
138 | self._outVariableList.append(outVariable)
139 | return outVariable
140 |
141 | # Return the number of unique variables that have been copied.
142 | def getNUniqueVariables(self):
143 | return len(self._inVariableList)
144 |
145 |
--------------------------------------------------------------------------------
/source/python/examples/Benchmarks/naiveQueens.py:
--------------------------------------------------------------------------------
1 | import sys
2 | # Hack sys.path for the examples.
3 | sys.path.append("../..")
4 | from YP import *
5 | from Variable import *
6 | from Atom import *
7 | from ListPair import *
8 | from time import *
9 |
10 | def main():
11 | startTime = clock()
12 | nAnswers = 0
13 | Qs = Variable()
14 | for l1 in queens(11, Qs):
15 | nAnswers += 1
16 | finishTime = clock()
17 | print "Naive queens:", (finishTime - startTime), "seconds,", \
18 | nAnswers, "answers"
19 |
20 | def queens(N, Qs):
21 | Ns = Variable()
22 | for l1 in rangeList(1, N, Ns):
23 | for l2 in queens3(Ns, Atom.NIL, Qs):
24 | yield False
25 |
26 | def queens3(UnplacedQs, SafeQs, Qs):
27 | UnplacedQs1 = Variable()
28 | Q = Variable()
29 | for l1 in selectq(Q, UnplacedQs, UnplacedQs1):
30 | for l2 in notHasAttack(Q, SafeQs):
31 | for l3 in queens3(UnplacedQs1, ListPair(Q, SafeQs), Qs):
32 | yield False
33 | for l1 in YP.unify(UnplacedQs, Atom.NIL):
34 | for l2 in YP.unify(Qs, SafeQs):
35 | yield False
36 |
37 | def notHasAttack(X, Xs):
38 | for l1 in attack(X, Xs):
39 | return
40 | yield False
41 |
42 | def attack(X, Xs):
43 | for l1 in attack3(X, 1, Xs):
44 | yield False
45 |
46 | def attack3(X, N, Arg3):
47 | Y = Variable()
48 | for l1 in ListPair(Y, Variable()).unify(Arg3):
49 | if YP.getValue(X) == Y.getValue() + YP.getValue(N):
50 | yield False
51 | if YP.getValue(X) == Y.getValue() - YP.getValue(N):
52 | yield False
53 |
54 | Ys = Variable()
55 | N1 = Variable()
56 | for l1 in ListPair(Variable(), Ys).unify(Arg3):
57 | for l2 in N1.unify(YP.getValue(N) + 1):
58 | for l3 in attack3(X, N1, Ys):
59 | yield False
60 |
61 | def rangeList(M, N, List):
62 | if YP.getValue(M) >= YP.getValue(N):
63 | for l1 in YP.unify(List, ListPair(N, Atom.NIL)):
64 | yield False
65 | else:
66 | Tail = Variable()
67 | for l1 in rangeList(YP.getValue(M) + 1, YP.getValue(N), Tail):
68 | for l2 in YP.unify(List, ListPair(M, Tail)):
69 | yield False
70 |
71 |
72 | def selectq(X, Arg2, Arg3):
73 | for l1 in ListPair(X, Arg3).unify(Arg2):
74 | yield False
75 |
76 | Y = Variable()
77 | Ys = Variable()
78 | Zs = Variable()
79 | for l1 in ListPair(Y, Ys).unify(Arg2):
80 | for l2 in ListPair(Y, Zs).unify(Arg3):
81 | for l3 in selectq(X, Ys, Zs):
82 | yield False
83 |
84 | main()
85 |
86 |
87 |
--------------------------------------------------------------------------------
/source/python/examples/Benchmarks/queens.py:
--------------------------------------------------------------------------------
1 | import sys
2 | # Hack sys.path for the examples.
3 | sys.path.append("../..")
4 | from YP import *
5 | from Variable import *
6 | from Atom import *
7 | from ListPair import *
8 | from time import *
9 |
10 | def main():
11 | startTime = clock()
12 | nAnswers = 0
13 | Qs = Variable()
14 | for l1 in queens(11, Qs):
15 | nAnswers += 1
16 | finishTime = clock()
17 | print "Optimized queens:", (finishTime - startTime), "seconds,", \
18 | nAnswers, "answers"
19 |
20 | def queens(N, Qs):
21 | Ns = Variable()
22 | for l1 in rangeList(1, N, Ns):
23 | for l2 in queens3(Ns, Atom.NIL, Qs):
24 | yield False
25 |
26 | def queens3(UnplacedQs, SafeQs, Qs):
27 | UnplacedQsListPair = YP.getValue(UnplacedQs)
28 | if isinstance(UnplacedQsListPair, ListPair):
29 | UnplacedQs1 = Variable()
30 | Q = Variable()
31 | for l1 in selectq(Q, UnplacedQsListPair, UnplacedQs1):
32 | if not (isinstance(SafeQs, ListPair) and hasAttack(Q.getValue(), SafeQs)):
33 | for l2 in queens3(UnplacedQs1, ListPair(Q, SafeQs), Qs):
34 | yield False
35 | else:
36 | for l1 in Qs.unify(SafeQs):
37 | yield False
38 |
39 | def hasAttack(X, Xs):
40 | return hasAttack3(X, 1, Xs)
41 |
42 | def hasAttack3(X, N, Arg3):
43 | if X == YP.getValue(Arg3._arg1) + N or X == YP.getValue(Arg3._arg1) - N:
44 | return True
45 | if isinstance(Arg3._arg2, ListPair):
46 | return hasAttack3(X, N + 1, YP.getValue(Arg3._arg2))
47 | else:
48 | return False
49 |
50 | def rangeList(M, N, List):
51 | if M >= N:
52 | for l1 in List.unify(ListPair(N, Atom.NIL)):
53 | yield False
54 | else:
55 | Tail = Variable()
56 | for l1 in rangeList(M + 1, N, Tail):
57 | for l2 in List.unify(ListPair(M, Tail)):
58 | yield False
59 |
60 | def selectq(X, Arg2, Arg3):
61 | for l1 in X.unify(Arg2._arg1):
62 | for l2 in Arg3.unify(Arg2._arg2):
63 | yield False
64 |
65 | Arg2Tail = YP.getValue(Arg2._arg2)
66 | if isinstance(Arg2Tail, ListPair):
67 | Zs = Variable()
68 | for l1 in selectq(X, Arg2Tail, Zs):
69 | for l2 in Arg3.unify(ListPair(Arg2._arg1, Zs)):
70 | yield False
71 |
72 | main()
73 |
74 |
75 |
--------------------------------------------------------------------------------
/source/python/examples/YieldPrologTutorial/tutorial1.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | def main():
30 | print("Names using a return value:")
31 | for p in personWithReturnValue():
32 | print(p)
33 |
34 | print("Names using SimpleVariable:")
35 | P = SimpleVariable()
36 | for l1 in personWithSimpleVariable(P):
37 | print(P._value)
38 |
39 | print("Names using UnifyingVariable:")
40 | Person = UnifyingVariable()
41 | for l1 in personWithUnify(Person):
42 | print(Person._value)
43 |
44 | print("Use unify to check a person:")
45 | for l1 in Person.unify("Hillary"):
46 | for l2 in personWithUnify(Person):
47 | print("Hillary is a person.")
48 | for l1 in Person.unify("Buddy"):
49 | for l2 in personWithUnify(Person):
50 | # This won't print.
51 | print("Buddy is a person.")
52 |
53 | print("Use generalUnify to check a person:")
54 | for l1 in person("Hillary"):
55 | print("Hillary is a person.")
56 | for l1 in person("Buddy"):
57 | # This won't print.
58 | print ("Buddy is a person.")
59 |
60 | print("Find relations:")
61 | Brother = UnifyingVariable()
62 | for l1 in brother("Hillary", Brother):
63 | print("Hillary has brother " + Brother._value + ".")
64 |
65 | print("Joining functions:")
66 | Uncle = UnifyingVariable()
67 | for l1 in uncle(Person, Uncle):
68 | print(Person._value + " has uncle " + Uncle._value + ".")
69 |
70 | def personWithReturnValue():
71 | yield "Chelsea"
72 | yield "Hillary"
73 | yield "Bill"
74 |
75 | class SimpleVariable:
76 | pass
77 |
78 | def personWithSimpleVariable(Person):
79 | Person._value = "Chelsea"
80 | yield False
81 | Person._value = "Hillary"
82 | yield False
83 | Person._value = "Bill"
84 | yield False
85 |
86 | class UnifyingVariable:
87 | def __init__(self):
88 | self._isBound = False
89 |
90 | def unify(self, arg):
91 | if not self._isBound:
92 | self._value = arg
93 | self._isBound = True
94 | yield False
95 | # Remove the binding.
96 | self._isBound = False
97 | elif self._value == arg:
98 | yield False
99 |
100 | def personWithUnify(Person):
101 | for l1 in Person.unify("Chelsea"):
102 | yield False
103 | for l1 in Person.unify("Hillary"):
104 | yield False
105 | for l1 in Person.unify("Bill"):
106 | yield False
107 |
108 | def generalGetValue(value):
109 | if isinstance(value, UnifyingVariable):
110 | if not value._isBound:
111 | return value
112 | else:
113 | return value._value
114 | else:
115 | return value
116 |
117 | def generalUnify(arg1, arg2):
118 | arg1Value = generalGetValue(arg1)
119 | arg2Value = generalGetValue(arg2)
120 | if isinstance(arg1Value, UnifyingVariable):
121 | for l1 in arg1Value.unify(arg2Value):
122 | yield False
123 | elif isinstance(arg2Value, UnifyingVariable):
124 | for l1 in arg2Value.unify(arg1Value):
125 | yield False
126 | else:
127 | # Arguments are "normal" types.
128 | if arg1Value == arg2Value:
129 | yield False
130 |
131 | def person(Person):
132 | for l1 in generalUnify(Person, "Chelsea"):
133 | yield False
134 | for l1 in generalUnify(Person, "Hillary"):
135 | yield False
136 | for l1 in generalUnify(Person, "Bill"):
137 | yield False
138 |
139 | def brother(Person, Brother):
140 | for l1 in generalUnify(Person, "Hillary"):
141 | for l2 in generalUnify(Brother, "Tony"):
142 | yield False
143 | for l2 in generalUnify(Brother, "Hugh"):
144 | yield False
145 | for l1 in generalUnify(Person, "Bill"):
146 | for l2 in generalUnify(Brother, "Roger"):
147 | yield False
148 |
149 | def parent(Person, Parent):
150 | for l1 in generalUnify(Person, "Chelsea"):
151 | for l2 in generalUnify(Parent, "Hillary"):
152 | yield False
153 | for l1 in generalUnify(Person, "Chelsea"):
154 | for l2 in generalUnify(Parent, "Bill"):
155 | yield False
156 |
157 | def uncle(Person, Uncle):
158 | Parent = UnifyingVariable()
159 | for l1 in parent(Person, Parent):
160 | for l2 in brother(Parent, Uncle):
161 | yield False
162 |
163 | main()
164 |
--------------------------------------------------------------------------------
/source/python/examples/YieldPrologTutorial/tutorial2.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import sys
30 | # Hack sys.path for the examples.
31 | sys.path.append("../..")
32 | from YP import *
33 | from Variable import *
34 |
35 | def main():
36 | Brother = Variable()
37 | print "Find relations:"
38 | for l1 in brother("Hillary", Brother):
39 | print "Hillary has brother", \
40 | Brother.getValue(), "."
41 |
42 | print "Check if it is square:"
43 | for l1 in squaredRectangle(10, 10):
44 | print "10 by 10 rectangle is square."
45 |
46 | print "Make it square:"
47 | Width = Variable()
48 | Height = Variable()
49 | for l1 in Width.unify(10):
50 | for l2 in squaredRectangle(Width, Height):
51 | print "A square of width", \
52 | Width.getValue(), "has height", \
53 | Height.getValue(), "."
54 |
55 | print "Make it square before we know the width:"
56 | for l1 in squaredRectangle(Width, Height):
57 | for l2 in Width.unify(10):
58 | print "A square of width", \
59 | Width.getValue(), "has height", \
60 | Height.getValue(), "."
61 |
62 | print "Get one match:"
63 | for l1 in anyBrother("Hillary", Brother):
64 | print "Hillary has a brother", \
65 | Brother.getValue(), "."
66 | for l1 in anyBrother("Bill", Brother):
67 | print "Bill has a brother", \
68 | Brother.getValue(), "."
69 |
70 | print "Use cut for negation:"
71 | for l1 in noBrother("Hillary"):
72 | print "Hillary has no brother."
73 | for l1 in noBrother("Chelsea"):
74 | print "Chelsea has no brother."
75 |
76 | def brother(Person, Brother):
77 | for l1 in YP.unify(Person, "Hillary"):
78 | for l2 in YP.unify(Brother, "Tony"):
79 | yield False
80 | for l2 in YP.unify(Brother, "Hugh"):
81 | yield False
82 | for l1 in YP.unify(Person, "Bill"):
83 | for l2 in YP.unify(Brother, "Roger"):
84 | yield False
85 |
86 | def squaredRectangle(Width, Height):
87 | for l1 in YP.unify(Width, Height):
88 | yield False
89 |
90 | def anyBrother(Person, Brother):
91 | for l1 in brother(Person, Brother):
92 | yield False
93 | break
94 |
95 | def noBrother(Person):
96 | Brother = Variable()
97 | for l1 in brother(Person, Brother):
98 | return
99 | yield False
100 |
101 | main()
102 |
103 |
104 |
--------------------------------------------------------------------------------
/source/python/examples/YieldPrologTutorial/tutorial3.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import sys
30 | # Hack sys.path for the examples.
31 | sys.path.append("../..")
32 | from YP import *
33 | from Variable import *
34 | from Atom import *
35 | from ListPair import *
36 |
37 | def main():
38 | print "Return a list of 2 elements:"
39 | List = Variable()
40 | for l1 in makeList("a", "b", List):
41 | print "List =", List.getValue()
42 |
43 | print "Unify two lists:"
44 | Second = Variable()
45 | for l1 in makeList("x", Second,
46 | ListPair("x", ListPair("y", Atom.NIL))):
47 | print "The second element is", Second.getValue()
48 |
49 | def makeList(First, Second, List):
50 | list1 = ListPair(Second, Atom.NIL)
51 | result = ListPair(First, list1)
52 | for l1 in YP.unify(List, result):
53 | yield False
54 |
55 | main()
56 |
57 |
58 |
--------------------------------------------------------------------------------
/source/python/examples/YieldPrologTutorial/tutorial4.py:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2007-2008, Jeff Thompson
2 | #
3 | # All rights reserved.
4 | #
5 | # Redistribution and use in source and binary forms, with or without
6 | # modification, are permitted provided that the following conditions are met:
7 | #
8 | # * Redistributions of source code must retain the above copyright
9 | # notice, this list of conditions and the following disclaimer.
10 | # * Redistributions in binary form must reproduce the above copyright
11 | # notice, this list of conditions and the following disclaimer in the
12 | # documentation and/or other materials provided with the distribution.
13 | # * Neither the name of the copyright holder nor the names of its contributors
14 | # may be used to endorse or promote products derived from this software
15 | # without specific prior written permission.
16 | #
17 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 | # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 | # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 | # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 | # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 | # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 | # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | import sys
30 | # Hack sys.path for the examples.
31 | sys.path.append("../..")
32 | from YP import *
33 | from Atom import *
34 | from Compiler import *
35 | from ListPair import *
36 | from Variable import *
37 |
38 | def main():
39 | YP.assertFact(Atom.a("brother"), \
40 | [Atom.a("Hillary"), Atom.a("Hugh")])
41 | YP.assertFact(Atom.a("brother"), \
42 | [Atom.a("Hillary"), Atom.a("Tony")])
43 | YP.assertFact(Atom.a("brother"), \
44 | [Atom.a("Bill"), Atom.a("Roger")])
45 |
46 | Brother = Variable()
47 | print "Using dynamic assert:"
48 | for l1 in YP.matchDynamic \
49 | (Atom.a("brother"), \
50 | [Atom.a("Hillary"), Brother]):
51 | print "Hillary has brother", \
52 | Brother.getValue()
53 |
54 | prologCode = \
55 | "uncle(Person, Uncle) :- \n" + \
56 | " parent(Person, Parent), \n" + \
57 | " brother(Parent, Uncle). \n"
58 | print "# Compiled code:"
59 | compileAndWrite(prologCode)
60 |
61 | prologCode = \
62 | ":- import('', [parent/2]). \n" + \
63 | "uncle(Person, Uncle) :- \n" + \
64 | " parent(Person, Parent), \n" + \
65 | " brother(Parent, Uncle). \n"
66 | print "# Calling an imported function:"
67 | compileAndWrite(prologCode)
68 |
69 | prologCode = \
70 | "parent('Chelsea', 'Hillary'). \n" + \
71 | "parent('Chelsea', 'Bill'). \n" + \
72 | \
73 | "uncle(Person, Uncle) :- \n" + \
74 | " parent(Person, Parent), \n" + \
75 | " brother(Parent, Uncle). \n"
76 | print "# Calling a locally-defined function:"
77 | compileAndWrite(prologCode)
78 |
79 | prologCode = \
80 | ":- import('', [parent/2]). \n" + \
81 | "uncle(Person, Uncle) :- \n" + \
82 | " Goal = parent(Person, Parent), \n" + \
83 | " Goal, \n" + \
84 | " brother(Parent, Uncle). \n"
85 | print "# Calling a dynamic goal:"
86 | compileAndWrite(prologCode)
87 |
88 | print "Calling compiled code having a dynamic goal:"
89 | Person = Variable()
90 | Uncle = Variable()
91 | for l1 in uncle(Person, Uncle):
92 | print Person.getValue(), "has uncle", \
93 | Uncle.getValue()
94 |
95 | def compileAndWrite(prologCode):
96 | YP.tell(sys.stdout)
97 | YP.see(YP.StringReader(prologCode))
98 | TermList = Variable()
99 | PseudoCode = Variable()
100 | for l1 in parseInput(TermList):
101 | for l2 in makeFunctionPseudoCode \
102 | (TermList, PseudoCode):
103 | convertFunctionPython(PseudoCode)
104 | YP.seen()
105 |
106 | def getDeclaringClass():
107 | return globals()
108 |
109 | def parent(arg1, arg2):
110 | for l1 in YP.unify \
111 | (arg1, Atom.a("Chelsea")):
112 | for l2 in YP.unify \
113 | (arg2, Atom.a("Hillary")):
114 | yield False
115 | for l1 in YP.unify \
116 | (arg1, Atom.a("Chelsea")):
117 | for l2 in YP.unify \
118 | (arg2, Atom.a("Bill")):
119 | yield False
120 |
121 | def uncle(Person, Uncle):
122 | Goal = Variable()
123 | Parent = Variable()
124 | for l1 in YP.unify \
125 | (Goal, Functor2 \
126 | (Atom.a("parent", Atom.a("")), \
127 | Person, Parent)):
128 | for l2 in YP.getIterator \
129 | (Goal, getDeclaringClass()):
130 | for l3 in YP.matchDynamic \
131 | (Atom.a("brother"), [Parent, Uncle]):
132 | yield False
133 |
134 | main()
135 |
136 |
137 |
--------------------------------------------------------------------------------