[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\n[Xx]64/\n[Xx]86/\n[Bb]uild/\nbld/\n[Bb]in/\n[Oo]bj/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n\n# TODO: Un-comment the next line if you do not want to checkin \n# your web deploy settings because they may include unencrypted\n# passwords\n#*.pubxml\n*.publishproj\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Microsoft Azure ApplicationInsights config file\nApplicationInsights.config\n\n# Windows Store app package directory\nAppPackages/\nBundleArtifacts/\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# LightSwitch generated files\nGeneratedArtifacts/\nModelManifest.xml\n\n# Paket dependency manager\n.paket/paket.exe\n\n# FAKE - F# Make\n.fake/"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "How to Contribute to aima-csharp\n==========================\n\nThanks for considering contributing to `aima-csharp`! Whether you are an aspiring [Google Summer of Code](https://summerofcode.withgoogle.com/organizations/5663121491361792/) student, or an independent contributor, here is a guide to how you can help:\n\n## Read the Code and Start on an Issue\n\n- First, read and understand the code to get a feel for the extent and the style.\n- Look at the [issues](https://github.com/aimacode/aima-csharp/issues) and pick one to work on.\n- One of the issues is that some algorithms are missing from the [list of algorithms](/README.md#index-of-implemented-algorithms).\n\n## New and Improved Algorithms\n\n- Implement functions that were in the third edition of the book but were not yet implemented in the code. Check the [list of pseudocode algorithms (pdf)](https://github.com/aimacode/pseudocode/blob/master/aima3e-algorithms.pdf) to see what's missing.\n- As we finish chapters for the new fourth edition, we will share the new pseudocode in the [`aima-pseudocode`](https://github.com/aimacode/aima-pseudocode) repository, and describe what changes are necessary.\nWe hope to have a `algorithm-name.md` file for each algorithm, eventually; it would be great if contributors could add some for the existing algorithms.\n\n\nContributing a Patch\n====================\n\n1. Submit an issue describing your proposed change to the repo in question (or work on an existing issue).\n1. The repo owner will respond to your issue promptly.\n1. Fork the desired repo, develop and test your code changes.\n1. Submit a pull request.\n\nReporting Issues\n================\n\n- Under which versions of Visual Studio does this happen?\n\n- Is anybody working on this?\n\n# Choice of Programming Languages\n\nAre we right to concentrate on Java and Python versions of the code? I think so; both languages are popular; Java is\nfast enough for our purposes, and has reasonable type declarations (but can be verbose); Python is popular and has a very direct mapping to the pseudocode in the book (but lacks type declarations and can be slow). The [TIOBE Index](http://www.tiobe.com/tiobe_index) says the top seven most popular languages, in order, are:\n\n        Java, C, C++, C#, Python, PHP, Javascript\n\nSo it might be reasonable to also support C++/C# at some point in the future. It might also be reasonable to support a language that combines the terse readability of Python with the type safety and speed of Java; perhaps Go or Julia. I see no reason to support PHP. Javascript is the language of the browser; it would be nice to have code that runs in the browser without need for any downloads; this would be in Javascript or a variant such as Typescript.\n\nThere is also a `aima-lisp` project; in 1995 when we wrote the first edition of the book, Lisp was the right choice, but today it is less popular (currently #31 on the TIOBE index).\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2018 aimacode\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# ![](https://github.com/aimacode/aima-java/blob/gh-pages/aima3e/images/aima3e.jpg)aima-csharp\nC# implementation of algorithms from [Russell](http://www.cs.berkeley.edu/~russell/) And [Norvig's](http://www.norvig.com/) [Artificial Intelligence - A Modern Approach 3rd Edition](http://aima.cs.berkeley.edu/). You can use this in conjunction with a course on AI, or for study on your own.\n\n## Index of Implemented Algorithms\n\nHere is a table of algorithms, the figure, name of the code in the book, and the file where they are implemented in the code. This chart was made for the third edition of the book and needs to be updated for the upcoming fourth edition. Empty implementations are a good place for contributors to look for an issue. The [aima-pseudocode](https://github.com/aimacode/aima-pseudocode) project describes all the algorithms from the book.\n\n|Fig|Page|Name (in book)|Code|\n| -------- |:--------:| :-----| :----- |\n|2|34|Environment|[Environment](/aima-csharp/agent/Environment.cs)|\n|2.1|35|Agent|[Agent](/aima-csharp/agent/Agent.cs)|\n|2.3|36|Table-Driven-Vacuum-Agent||\n|2.7|47|Table-Driven-Agent|[TableDrivenAgentProgram](/aima-csharp/agent/impl/aprog/TableDrivenAgentProgram.cs)|\n|2.8|48|Reflex-Vacuum-Agent|[?ReflexVacuumAgent?](/aima-csharp/agent/impl/aprog/ModelBasedReflexAgentProgram.cs)|\n|2.10|49|Simple-Reflex-Agent|[SimpleReflexAgentProgram](/aima-csharp/agent/impl/aprog/SimpleReflexAgentProgram.cs)|\n|2.12|51|Model-Based-Reflex-Agent|[ModelBasedReflexAgentProgram](/aima-csharp/agent/impl/aprog/ModelBasedReflexAgentProgram.cs)|\n|3|66|Problem|\n|3.1|67|Simple-Problem-Solving-Agent|[SimpleProblemSolvingAgent](/aima-csharp/search/framework/SimpleProblemSolvingAgent.cs)|\n|3.2|68|Romania|[SimplifiedRoadMapOfPartOfRomania](/aima-csharp/environment/map/SimplifiedRoadMapOfPartOfRomania.cs)|\n|3.7|77|Tree-Search|[TreeSearch](/aima-csharp/search/framework/qsearch/TreeSearch.cs)|\n|3.7|77|Graph-Search|[GraphSearch](/aima-csharp/search/framework/qsearch/GraphSearch.cs)|\n|3.10|79|Node|[Node](/aima-csharp/search/framework/Node.cs)|\n|3.11|82|Breadth-First-Search|\n|3.14|84|Uniform-Cost-Search|\n|3|85|Depth-first Search|\n|3.17|88|Depth-Limited-Search|\n|3.18|89|Iterative-Deepening-Search|\n|3|90|Bidirectional search|\n|3|92|Best-First search|\n|3|92|Greedy best-First search|\n|3|93|A\\* Search|\n|3.26|99|Recursive-Best-First-Search |\n|4.2|122|Hill-Climbing|\n|4.5|126|Simulated-Annealing|\n|4.8|129|Genetic-Algorithm|\n|4.11|136|And-Or-Graph-Search|\n|4|147|Online search problem|[OnlineSearchProblem](/aima-csharp/search/online/OnlineSearchProblem.cs)|\n|4.21|150|Online-DFS-Agent|[OnlineDFSAgent](/aima-csharp/search/online/OnlineDFSAgent.cs)|\n|4.24|152|LRTA\\*-Agent|[LRTAStarAgent](/aima-csharp/search/online/LRTAStarAgent.cs)|\n|5.3|166|Minimax-Decision|\n|5.7|170|Alpha-Beta-Search|\n|6|202|CSP|\n|6.1|204|Map CSP|\n|6.3|209|AC-3|\n|6.5|215|Backtracking-Search|\n|6.8|221|Min-Conflicts|\n|6.11|224|Tree-CSP-Solver|\n|7|235|Knowledge Base|\n|7.1|236|KB-Agent|[KBAgent](/aima-csharp/logic/propositional/agent/KBAgent.cs)|\n|7.7|244|Propositional-Logic-Sentence|[Sentence](/aima-csharp/logic/propositional/parsing/ast/Sentence.cs)|\n|7.10|248|TT-Entails|\n|7|253|Convert-to-CNF|\n|7.12|255|PL-Resolution|\n|7.15|258|PL-FC-Entails?|\n|7.17|261|DPLL-Satisfiable?|\n|7.18|263|WalkSAT|\n|7.20|270|Hybrid-Wumpus-Agent|\n|7.22|272|SATPlan|\n|9|323|Subst|\n|9.1|328|Unify|[Unifier](/aima-csharp/logic/fol/Unifier.cs)|\n|9.3|332|FOL-FC-Ask|[FOLFCAsk](/aima-csharp/logic/fol/inference/FOLFCAsk.cs)|\n|9.3|332|FOL-BC-Ask|[FOLBCAsk](/aima-csharp/logic/fol/inference/FOLBCAsk.cs)|\n|9|345|CNF|[CNFConverter](/aima-csharp/logic/fol/CNFConverter.cs)|\n|9|347|Resolution|[FOLTFMResolution](/aima-csharp/logic/fol/inference/FOLTFMResolution.cs)|\n|9|354|Demodulation||\n|9|354|Paramodulation|[Paramodulation](/aima-csharp/logic/fol/inference/Paramodulation.cs)|\n|9|345|Subsumption|[SubsumptionElimination](/aima-csharp/logic/fol/SubsumptionElimination.cs)|\n|10.9|383|Graphplan|---|\n|11.5|409|Hierarchical-Search|---|\n|11.8|414|Angelic-Search|---|\n|13.1|484|DT-Agent|---|\n|13|484|Probability-Model|\n|13|487|Probability-Distribution|\n|13|490|Full-Joint-Distribution|\n|14|510|Bayesian Network|\n|14.9|525|Enumeration-Ask|\n|14.11|528|Elimination-Ask|\n|14.13|531|Prior-Sample|\n|14.14|533|Rejection-Sampling|\n|14.15|534|Likelihood-Weighting|\n|14.16|537|GIBBS-Ask|\n|15.4|576|Forward-Backward|\n|15|578|Hidden Markov Model|\n|15.6|580|Fixed-Lag-Smoothing|\n|15|590|Dynamic Bayesian Network|\n|15.17|598|Particle-Filtering|\n|16.9|632|Information-Gathering-Agent|---|\n|17|647|Markov Decision Process|\n|17.4|653|Value-Iteration|\n|17.7|657|Policy-Iteration|\n|17.9|663|POMDP-Value-Iteration|---|\n|18.5|702|Decision-Tree-Learning|\n|18.8|710|Cross-Validation-Wrapper|---|\n|18.11|717|Decision-List-Learning|\n|18.24|734|Back-Prop-Learning|\n|18.34|751|AdaBoost|\n|19.2|771|Current-Best-Learning|---|\n|19.3|773|Version-Space-Learning|---|\n|19.8|786|Minimal-Consistent-Det|---|\n|19.12|793|FOIL|---|\n|21.2|834|Passive-ADP-Agent|\n|21.4|837|Passive-TD-Agent|\n|21.8|844|Q-Learning-Agent|\n|22.1|871|HITS|\n|23.5|894|CYK-Parse|\n|25.9|982|Monte-Carlo-Localization|\n\n# Index of data structures\n\nHere is a table of the implemented data structures, the figure, name of the implementation in the repository, and the file where they are implemented.\n\n| **Figure** | **Name (in repository)** | **File** |\n|:-----------|:-------------------------|:---------|\n| 3.2    | romania_map              | |\n| 4.9    | vacumm_world             | |\n| 4.23   | one_dim_state_space      | |\n| 6.1    | australia_map            | |\n| 7.13   | wumpus_world_inference   | |\n| 7.16   | horn_clauses_KB          | |\n| 17.1   | sequential_decision_environment | |\n| 18.2   | waiting_decision_tree    | |\n"
  },
  {
    "path": "aima-csharp/App.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<configuration>\n    <startup> \n        <supportedRuntime version=\"v4.0\" sku=\".NETFramework,Version=v4.5.2\" />\n    </startup>\n</configuration>"
  },
  {
    "path": "aima-csharp/Program.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace aima_csharp\n{\n    class Program\n    {\n        static void Main(string[] args)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "aima-csharp/Properties/AssemblyInfo.cs",
    "content": "﻿using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Information about an assembly is controlled through the following \n// set of attributes. Change these attribute values to modify the information\n// associated with an assembly.\n[assembly: AssemblyTitle(\"aima-csharp\")]\n[assembly: AssemblyDescription(\"\")]\n[assembly: AssemblyConfiguration(\"\")]\n[assembly: AssemblyCompany(\"\")]\n[assembly: AssemblyProduct(\"aima-csharp\")]\n[assembly: AssemblyCopyright(\"Copyright ©  2016\")]\n[assembly: AssemblyTrademark(\"\")]\n[assembly: AssemblyCulture(\"\")]\n\n// Setting ComVisible to false makes the types in this assembly not visible \n// to COM components.  If you need to access a type in this assembly from \n// COM, set the ComVisible attribute to true on that type.\n[assembly: ComVisible(false)]\n\n// The following GUID is for the ID of the typelib if this project is exposed to COM\n[assembly: Guid(\"125f53d5-1ccf-4daf-82fe-4324686cf417\")]\n\n// Version information for an assembly consists of the following four values:\n//\n//      Major Version\n//      Minor Version \n//      Build Number\n//      Revision\n//\n// You can specify all the values or you can default the Build and Revision Numbers \n// by using the '*' as shown below:\n// [assembly: AssemblyVersion(\"1.0.*\")]\n[assembly: AssemblyVersion(\"1.0.0.0\")]\n[assembly: AssemblyFileVersion(\"1.0.0.0\")]\n"
  },
  {
    "path": "aima-csharp/agent/Action.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{\n    /**\n     * Describes an Action that can or has been taken by an Agent via one of its Actuators. \n     *\n     * @author Ciaran O'Reilly\n     */\n     public interface Action\n     {\n         /**\n\t  * Indicates whether or not this Action is a 'No Operation'.<br>\n\t  * Note: AIMA3e - NoOp, or no operation, is the name of an assembly language\n\t  * instruction that does nothing.\n\t  * \n\t  * @return true if this is a NoOp Action.\n\t  */\n         bool isNoOp();\n     }\n}"
  },
  {
    "path": "aima-csharp/agent/Agent.cs",
    "content": "using System;\nusing System.Collections;\n\nnamespace aima.core.agent\n{\n    /**\n    * Artificial Intelligence A Modern Approach (3rd Edition): Figure 2.1, page 35.<br>\n    * \n    * Figure 2.1 Agents interact with environments through sensors and actuators.\n    * \n    * @author Ravi Mohan\n    * @author Ciaran O'Reilly\n    */\n    public interface Agent : EnvironmentObject\n    {\n        /**\n\t * Call the Agent's program, which maps any given percept sequences to an\n\t * action.\n\t * \n\t * @param percept\n\t *            The current percept of a sequence perceived by the Agent.\n\t * @return the Action to be taken in response to the currently perceived\n\t *         percept.\n\t */\n        Action execute(Percept percept);\n\n        /**\n\t * Life-cycle indicator as to the liveness of an Agent.\n\t * \n\t * @return true if the Agent is to be considered alive, false otherwise.\n\t */\n        bool isAlive();\n\n        /**\n\t * Set the current liveness of the Agent.\n\t * \n\t * @param alive\n\t *            set to true if the Agent is to be considered alive, false\n\t *            otherwise.\n\t */\n        void setAlive(bool alive);\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/AgentProgram.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{\n    /**\n    * Artificial Intelligence A Modern Approach (3rd Edition): pg 35.<br>\n    * An agent's behavior is described by the 'agent function' that maps any given\n    * percept sequence to an action. Internally, the agent function for an\n    * artificial agent will be implemented by an agent program.\n    * \n    * @author Ravi Mohan\n    * @author Ciaran O'Reilly\n    */\n    public interface AgentProgram\n    {\n        /**\n\t * The Agent's program, which maps any given percept sequences to an action.\n\t * \n\t * @param percept\n\t *            The current percept of a sequence perceived by the Agent.\n\t * @return the Action to be taken in response to the currently perceived\n\t *         percept.\n\t */\n        Action execute(Percept percept);\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/Environment.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{\n    /**\n     * An abstract description of possible discrete Environments in which Agent(s)\n     * can perceive and act.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n    public interface Environment\n    {\n        /**\n\t * Returns the Agents belonging to this Environment.\n\t * \n\t * @return The Agents belonging to this Environment.\n\t */\n        List<Agent> getAgents();\n        \n        /**\n         * Add an agent to the Environment.\n         * \n         * @param agent\n         *            the agent to be added.\n         */\n        void addAgent(Agent agent);\n         \n        /**\n         * Remove an agent from the environment.\n         * \n         * @param agent\n         *            the agent to be removed.\n         */\n        void removeAgent(Agent agent);\n         \n        /**\n\t * Returns the EnvironmentObjects that exist in this Environment.\n\t * \n\t * @return the EnvironmentObjects that exist in this Environment.\n\t */\n        List<EnvironmentObject> getEnvironmentObjects();\n\n        /**\n\t * Add an EnvironmentObject to the Environment.\n\t * \n\t * @param eo\n\t *            the EnvironmentObject to be added.\n\t */\n        void addEnvironmentObject(EnvironmentObject eo);\n\n        /**\n         * Remove an EnvironmentObject from the Environment.\n         * \n         * @param eo\n         *            the EnvironmentObject to be removed.\n         */\n        void removeEnvironmentObject(EnvironmentObject eo);\n\n        /**\n         * Move the Environment one time step forward.\n         */\n        void step();\n\n        /**\n         * Move the Environment n time steps forward.\n         * \n         * @param n\n         *            the number of time steps to move the Environment forward.\n         */\n        void step(int n);\n\n        /**\n         * Step through time steps until the Environment has no more tasks.\n         */\n        void stepUntilDone();\n\n        /**\n\t * Returns <code>true</code> if the Environment is finished with its current\n\t * task(s).\n\t * \n\t * @return <code>true</code> if the Environment is finished with its current\n\t *         task(s).\n\t */\n        bool isDone();\n\n        /**\n         * Retrieve the performance measure associated with an Agent.\n         * \n         * @param forAgent\n         *            the Agent for which a performance measure is to be retrieved.\n         * @return the performance measure associated with the Agent.\n         */\n        double getPerformanceMeasure(Agent forAgent);\n\n        /**\n         * Add a view on the Environment.\n         * \n         * @param ev\n         *            the EnvironmentView to be added.\n         */\n        void addEnvironmentView(EnvironmentView ev);\n\n        /**\n         * Remove a view on the Environment.\n         * \n         * @param ev\n         *            the EnvironmentView to be removed.\n         */\n        void removeEnvironmentView(EnvironmentView ev);\n\n        /**\n         * Notify all registered EnvironmentViews of a message.\n         * \n         * @param msg\n         *            the message to notify the registered EnvironmentViews with.\n         */\n        void notifyViews(String msg);\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/EnvironmentObject.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{\n    /**\n     * An interface used to indicate any object that can belong within an\n     * Environment.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public interface EnvironmentObject\n    {\n\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/EnvironmentState.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{\n    /**\n     * An interface used to indicate a possible state of an Environment.\n     * \n     * @author Ciaran O'Reilly\n     */\n    public interface EnvironmentState\n    {\n\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/EnvironmentView.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{\n    /**\n     * Allows external applications/logic to view the interaction of Agent(s) with\n     * an Environment.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n     public interface EnvironmentView\n    {\n        /**\n\t * A simple notification message from the Environment, from one of its\n\t * objects.\n\t *   \n\t * @param msg\n\t *            the message received.\n\t */\n        void notify(String msg);\n\n        /**\n\t * Indicates an Agent has been added to the environment and what it\n\t * perceives initially.\n\t * \n\t * @param agent\n\t *            the Agent just added to the Environment.\n\t * @param resultingState\n\t *            the EnvironmentState that resulted from the Agent being added\n\t *            to the Environment.\n\t */\n        void agentAdded(Agent agent, EnvironmentState resultingState);\n\n        /**\n\t * Indicates the Environment has changed as a result of an Agent's action.\n\t * \n\t * @param agent\n\t *            the Agent that performed the Action.\n\t * @param action\n\t *            the Action the Agent performed.\n\t * @param resultingState\n\t *            the EnvironmentState that resulted from the Agent's Action on\n\t *            the Environment.\n\t */\n        void agentActed(Agent agent, Action action, EnvironmentState resultingState);\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/EnvironmentViewNotifier.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n     public interface EnvironmentViewNotifier\n    {\n        /**\n\t * A simple notification message, to be forwarded to an Environment's\n\t * registered EnvironmentViews.\n\t * \n\t * @param msg\n\t *            the message to be forwarded to the EnvironmentViews.\n\t */\n        void notifyViews(String msg);\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/Model.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): pg 50.<br>\n     * \n     * This knowledge about \"how the world works\" - whether implemented in simple bool circuits\n     * or in complete scientific theories - is called a model of the world. An Agent that uses such a\n     * model is called a model-based agent.\n     *\n     * @author Ciaran O'Reilly\n     */\n     public interface Model\n    {\n\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/Percept.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{    \n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): pg 34.<br>\n     * We use the term percept to refer the agent's perceptual inputs at any given instant.\n     *\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public interface Percept\n    {\n\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/State.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): pg 50.<br>\n     * \n     * The most effective way to handle partial observability is for the agent to keep track of the\n     * part of the world it can't see now. That is, the agent should maintain some sort of internal\n     * state that depends on the percept history and thereby reflects at least some of the unobserved\n     * aspects of the current state.\n     *\n     * @author Ciaran O'Reilly\n     */\n    public interface State\n    {\n\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/AbstractAgent.cs",
    "content": "using System;\nusing aima.core.agent;\n\nnamespace aima.core.agent.impl\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n     public abstract class AbstractAgent : Agent\n    {\n        protected AgentProgram program;\n        private bool alive = true;\n\n        public AbstractAgent()\n        {\n\n        }\n\n        /**\n\t * Constructs an Agent with the specified AgentProgram.\n\t * \n\t * @param aProgram\n\t *            the Agent's program, which maps any given percept sequences to\n\t *            an action.\n\t */\n        public AbstractAgent(AgentProgram aProgram)\n        {\n            program = aProgram;\n        }\n\n        //START-Agent\n        public virtual Action execute(Percept p)\n        {\n            if(null != program)\n            {\n                return program.execute(p);\n            }\n            return NoOpAction.NO_OP;\n        }\n\n        public bool isAlive()\n        {\n            return alive;\n        }\n\n        public void setAlive(bool alive)\n        {\n            this.alive = alive;\n        }\n\n        //END-Agent\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/AbstractEnvironment.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.util;\n\nnamespace aima.core.agent.impl\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public abstract class AbstractEnvironment : Environment, EnvironmentViewNotifier\n    {\n        // Note: Use LinkedHashSet's in order to ensure order is respected as\n        // provide\n        // access to these elements via List interface.\n        protected LinkedHashSet<EnvironmentObject> envObjects = new LinkedHashSet<EnvironmentObject>();\n\n        protected LinkedHashSet<Agent> agents = new LinkedHashSet<Agent>();\n\n        protected LinkedHashSet<EnvironmentView> views = new LinkedHashSet<EnvironmentView>();\n\n        protected Dictionary<Agent, Double> performanceMeasures = new Dictionary<Agent, Double>();\n                \n        // PRUBLIC METHODS\n        \n        // Methods to be implemented by subclasses.\n        public abstract EnvironmentState getCurrentState();\n\n        public abstract EnvironmentState executeAction(Agent agent, Action action);\n\n        public abstract Percept getPerceptSeenBy(Agent anAgent);\n        /**\n         * Method for implementing dynamic environments in which not all changes\n         * are directly caused by agent action execution. The default implementation\n         * does nothing.\n         */\n        public void createExogenousChange() { }\n                \n        // START-Environment\n        public List<Agent> getAgents()\n        {\n            // Return as a List but also ensures the caller cannot modify\n            return new List<Agent>(agents);\n        }\n\n        public void addAgent(Agent a)\n        {\n            addEnvironmentObject(a);\n        }\n\n        public void removeAgent(Agent a)\n        {\n            removeEnvironmentObject(a);\n        }\n\n        public List<EnvironmentObject> getEnvironmentObjects()\n        {\n            // Return as a List but also ensures the caller cannot modify\n            return new List<EnvironmentObject>(envObjects);\n        }\n\n        public void addEnvironmentObject(EnvironmentObject eo)\n        {\n            envObjects.Add(eo);\n            if (eo is Agent)\n            {\n                Agent a = (Agent)eo;\n                if (!agents.Contains(a))\n                {\n                    agents.Add(a);\n                    this.updateEnvironmentViewsAgentAdded(a);\n                }\n            }\n        }\n\n        public void removeEnvironmentObject(EnvironmentObject eo)\n        {\n            envObjects.Remove(eo);\n            //agents.Remove(eo);\n        }\n\n        /**\n         * Central template method for controlling agent simulation. The\n         * concrete behavior is determined by the primitive operations\n         * {@link #getPerceptSeenBy(Agent)}, {@link #executeAction(Agent, Action)},\n         * and {@link #createExogenousChange()}.\n         */\n        public void step()\n        {\n            foreach (Agent agent in agents)\n            {\n                if (agent.isAlive())\n                {\n                    Action anAction = agent.execute(getPerceptSeenBy(agent));\n                    EnvironmentState es = executeAction(agent, anAction);\n                    updateEnvironmentViewsAgentActed(agent, anAction, es);\n                }\n            }\n            createExogenousChange();\n        }\n\n        public void step(int n)\n        {\n            for (int i = 0; i < n; i++)\n            {\n                step();\n            }\n        }\n\n        public void stepUntilDone()\n        {\n            while (!isDone())\n            {\n                step();\n            }\n        }\n\n        public bool isDone()\n        {\n            foreach (Agent agent in agents)\n            {\n                if (agent.isAlive())\n                {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        public double getPerformanceMeasure(Agent forAgent)\n        {\n            Double pm = performanceMeasures[forAgent];\n            if (null == pm)\n            {\n                pm = 0.0;\n                performanceMeasures[forAgent] = pm;\n            }\n\n            return pm;\n        }\n\n        public void addEnvironmentView(EnvironmentView ev)\n        {\n            views.Add(ev);\n        }\n\n        public void removeEnvironmentView(EnvironmentView ev)\n        {\n            views.Remove(ev);\n        }\n\n        public void notifyViews(String msg)\n        {\n            foreach (EnvironmentView ev in views)\n            {\n                ev.notify(msg);\n            }\n        }\n\n        // END-Environment\n      \n        // PROTECTED METHODS\n       \n        protected void updatePerformanceMeasure(Agent forAgent, double addTo)\n        {\n            performanceMeasures[forAgent] = getPerformanceMeasure(forAgent)\n                    + addTo;\n        }\n\n        protected void updateEnvironmentViewsAgentAdded(Agent agent)\n        {\n            foreach (EnvironmentView view in views)\n            {\n                view.agentAdded(agent, getCurrentState());\n            }\n        }\n\n        protected void updateEnvironmentViewsAgentActed(Agent agent, Action action,\n                EnvironmentState state)\n        {\n            foreach (EnvironmentView view in views)\n            {\n                view.agentActed(agent, action, state);\n            }\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/DynamicAction.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.agent.impl\n{\n    /**\n     * @author Ciaran O'Reilly\n     */\n    public class DynamicAction : ObjectWithDynamicAttributes,\n            Action\n    {\n        public const String ATTRIBUTE_NAME = \"name\";\n\n        public DynamicAction(String name)\n        {\n            this.setAttribute(ATTRIBUTE_NAME, name);\n        }\n\n        /**\n\t * Returns the value of the name attribute.\n\t * \n\t * @return the value of the name attribute.\n\t */\n        public String getName()\n        {\n            return (System.String)getAttribute(ATTRIBUTE_NAME);\n        }\n\n        // START-Action\n        public bool isNoOp()\n        {\n            return false;\n        }\n\n        // END-Action\n        public String describeType()\n        {\n            return this.GetType().Name;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/DynamicEnvironmentState.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.agent.impl\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n     public class DynamicEnvironmentState : ObjectWithDynamicAttributes, EnvironmentState\n    {\n        public DynamicEnvironmentState()\n        {\n\n        }\n\n        public String describeType()\n        {\n            return typeof(EnvironmentState).Name;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/DynamicPercept.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\nusing System.Diagnostics;\n\nnamespace aima.core.agent.impl\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class DynamicPercept : ObjectWithDynamicAttributes, Percept\n    {\n        public DynamicPercept()\n        {\n\n        }\n\n        public String describeType()\n        {\n            return typeof(Percept).Name;\n        }\n\n        /**\n\t * Constructs a DynamicPercept with one attribute\n\t * \n\t * @param key1\n\t *            the attribute key\n\t * @param value1\n\t *            the attribute value\n\t */\n        public DynamicPercept(Object key1, Object value1)\n        {\n            setAttribute(key1, value1);\n        }\n\n\n        /**\n         * Constructs a DynamicPercept with two attributes\n         * \n         * @param key1\n         *            the first attribute key\n         * @param value1\n         *            the first attribute value\n         * @param key2\n         *            the second attribute key\n         * @param value2\n         *            the second attribute value\n         */\n        public DynamicPercept(Object key1, Object value1, Object key2, Object value2)\n        {\n            setAttribute(key1, value1);\n            setAttribute(key2, value2);\n        }\n\n        /**\n\t * Constructs a DynamicPercept with an array of attributes\n\t * \n\t * @param keys\n\t *            the array of attribute keys\n\t * @param values\n\t *            the array of attribute values\n\t */\n        public DynamicPercept(Object[] keys, Object[] values)\n        {\n            Debug.Assert(keys.Length == values.Length);\n\n            for(int i = 0; i < keys.Length; i++)\n            {\n                setAttribute(keys[i], values[i]);\n            }\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/DynamicState.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.agent.impl\n{\n    /**\n     * @author Ciaran O'Reilly\n     */\n    public class DynamicState : ObjectWithDynamicAttributes, State\n    {\n        public DynamicState()\n        {\n\n        }\n\n\n        public String describeType()\n        {\n            return typeof(State).Name;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/NoOpAction.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.agent.impl\n{\n    public class NoOpAction : DynamicAction\n    {\n        public static readonly NoOpAction NO_OP = new NoOpAction();\n\n        // START-Action\n        public bool isNoOp()\n        {\n            return true;\n        }\n\n        //END-Action\n        private NoOpAction() : base(\"NoOp\")\n        {\n            \n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/ObjectWithDynamicAttributes.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Diagnostics;\n\nnamespace aima.core.agent.impl\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n     public abstract class ObjectWithDynamicAttributes\n    {\n        private Dictionary<Object, Object> attributes = new Dictionary<Object, Object>();\n\n        //PUBLIC METHODS\n\n        /**\n         * By default, returns the simple name of the underlying class as given in\n         * the source code.\n         * \n         * @return the simple name of the underlying class\n         */\n        public String describeType()\n        {\n            return this.GetType().Name;\n        }\n\n        /**\n\t * Returns a string representation of the object's current attributes\n\t * \n\t * @return a string representation of the object's current attributes\n\t */\n        public String describeAttributes()\n        {\n            StringBuilder sb = new StringBuilder();\n\n            sb.Append(\"[\");\n            bool first = true;\n            foreach (Object key in attributes.Keys)\n            {\n                if (first)\n                {\n                    first = false;\n                }\n                else\n                {\n                    sb.Append(\", \");\n                }\n\n                sb.Append(key);\n                sb.Append(\"==\");\n                sb.Append(attributes[key]);\n            }\n            sb.Append(\"]\");\n\n            return sb.ToString();\n        }\n\n        /**\n\t * Returns an unmodifiable view of the object's key set\n\t * \n\t * @return an unmodifiable view of the object's key set\n\t */\n        public HashSet<Object> getKeySet()\n        {\n            return new HashSet<Object>(attributes.Keys);\n        }\n\n        /**\n\t * Associates the specified value with the specified attribute key. If the\n\t * ObjectWithDynamicAttributes previously contained a mapping for the\n\t * attribute key, the old value is replaced.\n\t * \n\t * @param key\n\t *            the attribute key\n\t * @param value\n\t *            the attribute value\n\t */\n        public void setAttribute(Object key, Object value)\n        {\n            attributes[key] = value;\n        }\n\n        /**\n\t * Returns the value of the specified attribute key, or null if the\n\t * attribute was not found.\n\t * \n\t * @param key\n\t *            the attribute key\n\t * \n\t * @return the value of the specified attribute name, or null if not found.\n\t */\n        public Object getAttribute(Object key)\n        {\n            return attributes[key];\n        }\n\n        /**\n\t * Removes the attribute with the specified key from this\n\t * ObjectWithDynamicAttributes.\n\t * \n\t * @param key\n\t *            the attribute key\n\t */\n        public void removeAttribute(Object key)\n        {\n            attributes.Remove(key);\n        }\n\n\n        /**\n         * Creates and returns a copy of this ObjectWithDynamicAttributes\n         */\n        public ObjectWithDynamicAttributes copy()\n        {\n            ObjectWithDynamicAttributes copy = null;\n\n            try\n            {\n                copy = (ObjectWithDynamicAttributes)this.GetType().GetConstructor(System.Type.EmptyTypes).Invoke(null);\n                foreach (object val in attributes)\n                {\n                    copy.attributes.Add(val, attributes[val]);\n                }\n            }\n            catch (Exception ex)\n            {\n                Debug.WriteLine(ex.ToString());\n            }\n\n            return copy;\n        }\n\n        public override bool Equals(Object o)\n        {\n            if (o == null || this.GetType() != o.GetType())\n            {\n                return base.Equals(o);\n            }\n            return attributes.Equals(((ObjectWithDynamicAttributes)o).attributes);\n        }\n\n        public override int GetHashCode()\n        {\n            return attributes.GetHashCode();\n        }\n\n        public override String ToString()\n        {\n            StringBuilder sb = new StringBuilder();\n\n            sb.Append(describeType());\n            sb.Append(describeAttributes());\n\n            return sb.ToString();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/SimpleEnvironmentView.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.agent.impl\n{\n    /**\n     * Simple environment view which uses the standard output stream to inform about\n     * relevant events.\n     * \n     * @author Ruediger Lunde\n     */\n    public class SimpleEnvironmentView : EnvironmentView\n    {\n        public void agentActed(Agent agent, Action action, EnvironmentState resultingState)\n        {\n            System.Console.WriteLine(\"Agent acted: \" + action.ToString());\n        }\n\n        public void agentAdded(Agent agent, EnvironmentState resultingState)\n        {\n            System.Console.WriteLine(\"Agent added.\");\n        }\n\n        public void notify(string msg)\n        {\n            System.Console.WriteLine(\"Message: \" + msg);\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/aprog/ModelBasedReflexAgentProgram.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl.aprog.simplerule;\n\nnamespace aima.core.agent.impl.aprog\n{\n    /**\n * Artificial Intelligence A Modern Approach (3rd Edition): Figure 2.12, page\n * 51.<br>\n * <br>\n * \n * <pre>\n * function MODEL-BASED-REFLEX-AGENT(percept) returns an action\n *   persistent: state, the agent's current conception of the world state\n *               model, a description of how the next state depends on current state and action\n *               rules, a set of condition-action rules\n *               action, the most recent action, initially none\n *               \n *   state  <- UPDATE-STATE(state, action, percept, model)\n *   rule   <- RULE-MATCH(state, rules)\n *   action <- rule.ACTION\n *   return action\n * </pre>\n * \n * Figure 2.12 A model-based reflex agent. It keeps track of the current state\n * of the world using an internal model. It then chooses an action in the same\n * way as the reflex agent.\n * \n * @author Ciaran O'Reilly\n * @author Mike Stampone\n * \n */\n\n    public abstract class ModelBasedReflexAgentProgram : AgentProgram\n    {\n        // persistent: state, the agent's current conception of the world state\n        private DynamicState state = null;\n\n        // model, a description of how the next state depends on current state and\n        // action\n        private Model model = null;\n\n        // rules, a set of condition-action rules\n        private HashSet<Rule> rules = null;\n\n        // action, the most recent action, initially none\n        private Action action = null;\n\n        public ModelBasedReflexAgentProgram()\n        {\n            init();\n        }\n\n        /**\n\t * Set the agent's current conception of the world state.\n\t * \n\t * @param state\n\t *            the agent's current conception of the world state.\n\t */\n         public void setState(DynamicState dstate)\n        {\n            state = dstate;\n        }\n\n        /**\n\t * Set the program's description of how the next state depends on the state\n\t * and action.\n\t * \n\t * @param model\n\t *            a description of how the next state depends on the current\n\t *            state and action.\n\t */\n         public void setModel(Model mod)\n        {\n            model = mod;\n        }\n\n        /**\n\t * Set the program's condition-action rules\n\t * \n\t * @param ruleSet\n\t *            a set of condition-action rules\n\t */\n        public void setRules(HashSet<Rule> ruleSet)\n        {\n            rules = ruleSet;\n        }\n\n        //START-AgentProgram\n\n        // function MODEL-BASED-REFLEX-AGENT(percept) returns an action\n        public Action execute(Percept percept)\n        {\n            // state <- UPDATE-STATE(state, action, percept, model)\n            state = updateState(state, action, percept, model);\n            // rule <- RULE-MATCH(state, rules)\n            Rule rule = ruleMatch(state, rules);\n            // action <- rule.ACTION\n            action = ruleAction(rule);\n            // return action\n            return action;\n        }\n\n        // END-AgentProgram\n\n        // PROTECTED METHODS\n\n        /**\n         * Realizations of this class should implement the init() method so that it\n\t * calls the setState(), setModel(), and setRules() method.\n\t */\n        protected abstract void init();\n\n        protected abstract DynamicState updateState(DynamicState state, Action action, Percept percept, Model model);\n\n        protected Rule ruleMatch(DynamicState state, HashSet<Rule> rules)\n        {\n            foreach (Rule r in rules)\n            {\n                if (r.evaluate(state))\n                {\n                    return r;\n                }\n            }\n            return null;\n        }\n\n        protected Action ruleAction(Rule r)\n        {\n            return null == r ? NoOpAction.NO_OP : r.getAction();\n        }\n    }\n}\n"
  },
  {
    "path": "aima-csharp/agent/impl/aprog/SimpleReflexAgentProgram.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.agent.impl.aprog.simplerule;\n\nnamespace aima.core.agent.impl.aprog\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 2.10, page\n     * 49.<br>\n     * <br>\n     * \n     * <pre>\n     * function SIMPLE-RELEX-AGENT(percept) returns an action\n     *   persistent: rules, a set of condition-action rules\n     *        \n     * state  <- INTERPRET-INPUT(percept);\n     * rule   <- RULE-MATCH(state, rules);\n     * action <- rule.ACTION;\n     * return action\n     * </pre>            \n     * Figure 2.10 A simple reflex agent. It acts according to a rule whose\n     * condition matches the current state, as defined by the percept.\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     * \n     */\n     public class SimpleReflexAgentProgram : AgentProgram\n    {\n        // persistent: rules, a set of condition-action rules\n        private HashSet<Rule> rules;\n\n        /**\n\t * Constructs a SimpleReflexAgentProgram with a set of condition-action\n\t * rules.\n\t * \n\t * @param ruleSet\n\t *            a set of condition-action rules\n\t */\n         public SimpleReflexAgentProgram(HashSet<Rule> ruleSet)\n        {\n            rules = ruleSet;\n        }\n\n        // START-AgentProgram\n\n        // function SIMPLE-RELEX-AGENT(percept) returns an action\n        public Action execute(Percept percept)\n        {\n            // state <- INTERPRET-INPUT(percept);\n            ObjectWithDynamicAttributes state = interpretInput(percept);\n            // rule <- RULE-MATCH(state, rules);\n            Rule rule = ruleMatch(state, rules);\n            // action <- rule.ACTION;\n            // return action\n            return ruleAction(rule);\n        }\n\n        // END-AgentProgram\n\n        // PROTECTED METHODS\n\n        protected ObjectWithDynamicAttributes interpretInput(Percept p)\n        {\n            return (DynamicPercept)p;\n        }\n\n        protected Rule ruleMatch(ObjectWithDynamicAttributes state,\n                HashSet<Rule> rulesSet)\n        {\n            foreach (Rule r in rulesSet)\n            {\n                if (r.evaluate(state))\n                {\n                    return r;\n                }\n            }\n            return null;\n        }\n\n        protected Action ruleAction(Rule r)\n        {\n            return null == r ? NoOpAction.NO_OP : r.getAction();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/aprog/TableDrivenAgentProgram.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.util;\n\nnamespace aima.core.agent.impl.aprog\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 2.7, page 47.<br>\n     * <br>\n     * \n     * <pre>\n     * function TABLE-DRIVEN-AGENT(percept) returns an action\n     *   persistent: percepts, a sequence, initially empty\n     *               table, a table of actions, indexed by percept sequences, initially fully specified\n     *           \n     *   append percept to end of percepts\n     *   action <- LOOKUP(percepts, table)\n     *   return action\n     * </pre>\n     * \n     * Figure 2.7 The TABLE-DRIVEN-AGENT program is invoked for each new percept and\n     * returns an action each time. It retains the complete percept sequence in\n     * memory.\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     * \n     */\n    public class TableDrivenAgentProgram : AgentProgram\n    {\n        private List<Percept> percepts = new List<Percept>();\n\n        private Table<List<Percept>, System.String, Action> table;\n\n        private const System.String ACTION = \"action\";\n\n        // persistent: percepts, a sequence, initially empty\n        // table, a table of actions, indexed by percept sequences, initially fully\n        // specified\n        /**\n         * Constructs a TableDrivenAgentProgram with a table of actions, indexed by\n         * percept sequences.\n         * \n         * @param perceptSequenceActions\n         *            a table of actions, indexed by percept sequences\n         */\n        public TableDrivenAgentProgram(Dictionary<List<Percept>, Action> perceptSequenceActions)\n        {\n            List<List<Percept>> rowHeaders = new List<List<Percept>>(perceptSequenceActions.Keys);\n\n            List<System.String> colHeaders = new List<System.String>();\n            colHeaders.Add(ACTION);\n\n            table = new Table<List<Percept>, System.String, Action>(rowHeaders, colHeaders);\n\n            foreach (List<Percept> row in rowHeaders)\n            {\n                table.set(row, ACTION, perceptSequenceActions[row]);\n            }\n        }\n\n        // START-AgentProgram\n\n        // function TABLE-DRIVEN-AGENT(percept) returns an action\n        public Action execute(Percept percept)\n        {\n            // append percept to end of percepts\n            percepts.Add(percept);\n\n            // action <- LOOKUP(percepts, table)\n            // return action\n            return lookupCurrentAction();\n        }\n\n        //END-AgentProgram\n\n        //PRIVATE METHODS\n        private Action lookupCurrentAction()\n        {\n            Action action = null;\n\n            action = table.get(percepts, ACTION);\n            if (null == action)\n            {\n                action = NoOpAction.NO_OP;\n            }\n\n            return action;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/aprog/simplerule/ANDCondition.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Diagnostics;\nusing aima.core.agent.impl;\n\nnamespace aima.core.agent.impl.aprog.simplerule\n{\n    /**\n     * Implementation of an AND condition.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ANDCondition : Condition\n    {\n        private Condition left;\n\n        private Condition right;\n\n        public ANDCondition(Condition leftCon, Condition rightCon)\n        {\n            Debug.Assert(null != leftCon);\n            Debug.Assert(null != rightCon);\n\n            left = leftCon;\n            right = rightCon;\n        }\n\n        public override bool evaluate(ObjectWithDynamicAttributes p)\n        {\n            return (left.evaluate(p) && right.evaluate(p));\n        }\n\n        public override String ToString()\n        {\n            StringBuilder sb = new StringBuilder();\n\n            return sb.Append(\"[\").Append(left).Append(\" && \").Append(right).Append(\n                    \"]\").ToString();\n        }\n    }    \n}"
  },
  {
    "path": "aima-csharp/agent/impl/aprog/simplerule/Condition.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent.impl;\n\nnamespace aima.core.agent.impl.aprog.simplerule\n{\n    /**\n     * Base abstract class for describing conditions.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n     public abstract class Condition\n    {\n        public abstract bool evaluate(ObjectWithDynamicAttributes p);\n\n        public bool Equals(Object o)\n        {\n            if(o == null || !(o is Condition))\n            {\n                return base.Equals(o);\n            }\n            return (ToString().Equals(((Condition)o).ToString()));\n        }\n\n        public override int GetHashCode()\n        {\n            return ToString().GetHashCode();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/aprog/simplerule/EQUALCondition.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Diagnostics;\nusing aima.core.agent.impl;\n\nnamespace aima.core.agent.impl.aprog.simplerule\n{\n    /**\n     * Implementation of an EQUALity condition.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n     public class EQUALCondition : Condition\n    {\n        private Object key;\n\n        private Object value;\n\n        public EQUALCondition(Object k, Object val)\n        {\n            Debug.Assert(null != key);\n            Debug.Assert(null != value);\n\n            key = k;\n            value = val;\n        }\n\n        public override bool evaluate(ObjectWithDynamicAttributes p)\n        {\n            return value.Equals(p.getAttribute(key));\n        }\n\n        public override String ToString()\n        {\n            StringBuilder sb = new StringBuilder();\n\n            return sb.Append(key).Append(\"==\").Append(value).ToString();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/aprog/simplerule/NOTCondition.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Diagnostics;\nusing aima.core.agent.impl;\n\nnamespace aima.core.agent.impl.aprog.simplerule\n{\n    /**\n     * Implementation of a NOT condition.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class NOTCondition : Condition\n    {\n        private Condition con;\n\n        public NOTCondition(Condition c)\n        {\n            Debug.Assert(null != con);\n\n            con = c;\n        }\n\n        public override bool evaluate(ObjectWithDynamicAttributes p)\n        {\n            return (!con.evaluate(p));\n        }\n\n        public override String ToString()\n        {\n            StringBuilder sb = new StringBuilder();\n\n            return sb.Append(\"![\").Append(con).Append(\"]\").ToString();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/aprog/simplerule/ORCondition.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Diagnostics;\nusing aima.core.agent.impl;\n\nnamespace aima.core.agent.impl.aprog.simplerule\n{\n    /**\n     * Implementation of an OR condition.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ORCondition : Condition\n    {\n        private Condition left;\n\n        private Condition right;\n\n        public ORCondition(Condition leftCon, Condition rightCon)\n        {\n            Debug.Assert(null != leftCon);\n            Debug.Assert(null != rightCon);\n\n            left = leftCon;\n            right = rightCon;\n        }\n\n        public override bool evaluate(ObjectWithDynamicAttributes p)\n        {\n            return (left.evaluate(p) || right.evaluate(p));\n        }\n\n        public override String ToString()\n        {\n            StringBuilder sb = new StringBuilder();\n\n            return sb.Append(\"[\").Append(left).Append(\" || \").Append(right).Append(\n                    \"]\").ToString();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/agent/impl/aprog/simplerule/Rule.cs",
    "content": "using System.Collections.Generic;\nusing System.Text;\nusing System.Diagnostics;\nusing aima.core.agent;\nusing aima.core.agent.impl;\n\nnamespace aima.core.agent.impl.aprog.simplerule\n{\n    /**\n     * A simple implementation of a \"condition-action rule\".\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n     public class Rule\n    {\n        private Condition con;\n\n        private Action action;\n\n\n        /**\n         * Constructs a condition-action rule.\n         * \n         * @param con\n         *            a condition\n         * @param action\n         *            an action\n         */\n        public Rule(Condition c, Action act)\n        {\n            Debug.Assert(null != con);\n            Debug.Assert(null != action);\n\n            con = c;\n            action = act;\n        }\n\n        public bool evaluate(ObjectWithDynamicAttributes p)\n        {\n            return (con.evaluate(p));\n        }\n\n        /**\n\t * Returns the action of this condition-action rule.\n\t * \n\t * @return the action of this condition-action rule.\n\t */\n        public Action getAction()\n        {\n            return action;\n        }\n\n        public override bool Equals(System.Object o)\n        {\n            if (o == null || !(o is Rule))\n            {\n                return base.Equals(o);\n            }\n            return (ToString().Equals(((Rule)o).ToString()));\n        }\n\n        public override int GetHashCode()\n        {\n            return ToString().GetHashCode();\n        }\n\n        public override System.String ToString()\n        {\n            StringBuilder sb = new StringBuilder();\n\n            return sb.Append(\"if \").Append(con).Append(\" then \").Append(action)\n                    .Append(\".\").ToString();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/aima-csharp.csproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"14.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props\" Condition=\"Exists('$(MSBuildExtensionsPath)\\$(MSBuildToolsVersion)\\Microsoft.Common.props')\" />\n  <PropertyGroup>\n    <Configuration Condition=\" '$(Configuration)' == '' \">Debug</Configuration>\n    <Platform Condition=\" '$(Platform)' == '' \">AnyCPU</Platform>\n    <ProjectGuid>{125F53D5-1CCF-4DAF-82FE-4324686CF417}</ProjectGuid>\n    <OutputType>Exe</OutputType>\n    <AppDesignerFolder>Properties</AppDesignerFolder>\n    <RootNamespace>aima_csharp</RootNamespace>\n    <AssemblyName>aima-csharp</AssemblyName>\n    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>\n    <FileAlignment>512</FileAlignment>\n    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugSymbols>true</DebugSymbols>\n    <DebugType>full</DebugType>\n    <Optimize>false</Optimize>\n    <OutputPath>bin\\Debug\\</OutputPath>\n    <DefineConstants>DEBUG;TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <PropertyGroup Condition=\" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' \">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n    <DebugType>pdbonly</DebugType>\n    <Optimize>true</Optimize>\n    <OutputPath>bin\\Release\\</OutputPath>\n    <DefineConstants>TRACE</DefineConstants>\n    <ErrorReport>prompt</ErrorReport>\n    <WarningLevel>4</WarningLevel>\n  </PropertyGroup>\n  <ItemGroup>\n    <Reference Include=\"System\" />\n    <Reference Include=\"System.Core\" />\n    <Reference Include=\"System.Xml.Linq\" />\n    <Reference Include=\"System.Data.DataSetExtensions\" />\n    <Reference Include=\"Microsoft.CSharp\" />\n    <Reference Include=\"System.Data\" />\n    <Reference Include=\"System.Net.Http\" />\n    <Reference Include=\"System.Xml\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Compile Include=\"agent\\Action.cs\" />\n    <Compile Include=\"agent\\Agent.cs\" />\n    <Compile Include=\"agent\\AgentProgram.cs\" />\n    <Compile Include=\"agent\\Environment.cs\" />\n    <Compile Include=\"agent\\EnvironmentObject.cs\" />\n    <Compile Include=\"agent\\EnvironmentState.cs\" />\n    <Compile Include=\"agent\\EnvironmentView.cs\" />\n    <Compile Include=\"agent\\EnvironmentViewNotifier.cs\" />\n    <Compile Include=\"agent\\impl\\AbstractAgent.cs\" />\n    <Compile Include=\"agent\\impl\\AbstractEnvironment.cs\" />\n    <Compile Include=\"agent\\impl\\aprog\\ModelBasedReflexAgentProgram.cs\" />\n    <Compile Include=\"agent\\impl\\aprog\\SimpleReflexAgentProgram.cs\" />\n    <Compile Include=\"agent\\impl\\aprog\\simplerule\\ANDCondition.cs\" />\n    <Compile Include=\"agent\\impl\\aprog\\simplerule\\Condition.cs\" />\n    <Compile Include=\"agent\\impl\\aprog\\simplerule\\EQUALCondition.cs\" />\n    <Compile Include=\"agent\\impl\\aprog\\simplerule\\NOTCondition.cs\" />\n    <Compile Include=\"agent\\impl\\aprog\\simplerule\\ORCondition.cs\" />\n    <Compile Include=\"agent\\impl\\aprog\\simplerule\\Rule.cs\" />\n    <Compile Include=\"agent\\impl\\aprog\\TableDrivenAgentProgram.cs\" />\n    <Compile Include=\"agent\\impl\\DynamicAction.cs\" />\n    <Compile Include=\"agent\\impl\\DynamicEnvironmentState.cs\" />\n    <Compile Include=\"agent\\impl\\DynamicPercept.cs\" />\n    <Compile Include=\"agent\\impl\\DynamicState.cs\" />\n    <Compile Include=\"agent\\impl\\NoOpAction.cs\" />\n    <Compile Include=\"agent\\impl\\ObjectWithDynamicAttributes.cs\" />\n    <Compile Include=\"agent\\impl\\SimpleEnvironmentView.cs\" />\n    <Compile Include=\"agent\\Model.cs\" />\n    <Compile Include=\"agent\\Percept.cs\" />\n    <Compile Include=\"agent\\State.cs\" />\n    <Compile Include=\"environment\\cellworld\\Cell.cs\" />\n    <Compile Include=\"environment\\cellworld\\CellWorld.cs\" />\n    <Compile Include=\"environment\\cellworld\\CellWorldAction.cs\" />\n    <Compile Include=\"environment\\cellworld\\CellWorldFactory.cs\" />\n    <Compile Include=\"environment\\eightpuzzle\\BidirectionalEightPuzzleProblem.cs\" />\n    <Compile Include=\"environment\\eightpuzzle\\EightPuzzleBoard.cs\" />\n    <Compile Include=\"environment\\eightpuzzle\\EightPuzzleFunctionFactory.cs\" />\n    <Compile Include=\"environment\\eightpuzzle\\EightPuzzleGoalTest.cs\" />\n    <Compile Include=\"environment\\eightpuzzle\\ManhattanHeuristicFunction.cs\" />\n    <Compile Include=\"environment\\eightpuzzle\\MisplacedTilleHeuristicFunction.cs\" />\n    <Compile Include=\"environment\\map\\AdaptableHeuristicFunction.cs\" />\n    <Compile Include=\"environment\\map\\BidirectionalMapProblem.cs\" />\n    <Compile Include=\"environment\\map\\DynAttributeNames.cs\" />\n    <Compile Include=\"environment\\map\\ExtendableMap.cs\" />\n    <Compile Include=\"environment\\map\\Map.cs\" />\n    <Compile Include=\"environment\\map\\MapAgent.cs\" />\n    <Compile Include=\"environment\\map\\MapEnvironment.cs\" />\n    <Compile Include=\"environment\\map\\MapEnvironmentState.cs\" />\n    <Compile Include=\"environment\\map\\MapFunctionFactory.cs\" />\n    <Compile Include=\"environment\\map\\MapStepCostFunction.cs\" />\n    <Compile Include=\"environment\\map\\MoveToAction.cs\" />\n    <Compile Include=\"environment\\map\\Scenario.cs\" />\n    <Compile Include=\"environment\\map\\SimplifiedRoadMapOfAustralia.cs\" />\n    <Compile Include=\"environment\\map\\SimplifiedRoadMapOfPartOfRomania.cs\" />\n    <Compile Include=\"environment\\map\\StraightLineDistanceHeuristicFunction.cs\" />\n    <Compile Include=\"environment\\wumpusworld\\AgentPercept.cs\" />\n    <Compile Include=\"environment\\wumpusworld\\AgentPosition.cs\" />\n    <Compile Include=\"environment\\wumpusworld\\ManhattanHeuristicFunction.cs\" />\n    <Compile Include=\"environment\\wumpusworld\\Room.cs\" />\n    <Compile Include=\"logic\\common\\Lexer.cs\" />\n    <Compile Include=\"logic\\common\\LexerException.cs\" />\n    <Compile Include=\"logic\\common\\LogicTokenTypes.cs\" />\n    <Compile Include=\"logic\\common\\Parser.cs\" />\n    <Compile Include=\"logic\\common\\ParserException.cs\" />\n    <Compile Include=\"logic\\common\\ParserTreeNode.cs\" />\n    <Compile Include=\"logic\\common\\Token.cs\" />\n    <Compile Include=\"logic\\fol\\CNFConverter.cs\" />\n    <Compile Include=\"logic\\fol\\Connectors.cs\" />\n    <Compile Include=\"logic\\fol\\domain\\DomainFactory.cs\" />\n    <Compile Include=\"logic\\fol\\domain\\FOLDomain.cs\" />\n    <Compile Include=\"logic\\fol\\domain\\FOLDomainAnswerLiteralAddedEvent.cs\" />\n    <Compile Include=\"logic\\fol\\domain\\FOLDomainEvent.cs\" />\n    <Compile Include=\"logic\\fol\\domain\\FOLDomainListener.cs\" />\n    <Compile Include=\"logic\\fol\\domain\\FOLDomainSkolemConstantAddedEvent.cs\" />\n    <Compile Include=\"logic\\fol\\domain\\FOLDomainSkolemFunctionAddedEvent.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\AbstractModulation.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\Demodulation.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\FOLBCAsk.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\FOLFCAsk.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\FOLModelElimination.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\FOLOTTERLikeTheoremProver.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\FOLTFMResolution.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\InferenceProcedure.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\InferenceResult.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\InferenceResultPrinter.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\otter\\ClauseFilter.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\otter\\ClauseSimplifier.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\otter\\defaultimpl\\DefaultClauseFilter.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\otter\\defaultimpl\\DefaultClauseSimplifier.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\otter\\defaultimpl\\DefaultLightestClauseHeuristic.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\otter\\LightestClauseHeuristic.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\Paramodulation.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\AbstractProofStep.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\Proof.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofFinal.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofPrinter.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStep.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepBwChGoal.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepChainCancellation.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepChainContrapositive.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepChainDropped.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepChainFromClause.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepChainReduction.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepClauseBinaryResolvent.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepClauseClausifySentence.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepClauseDemodulation.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepClauseFactor.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepClauseParamodulation.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepFoChAlreadyAFact.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepFoChAssertFact.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepGoal.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepPremise.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\proof\\ProofStepRenaming.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\trace\\FOLModelEliminationTracer.cs\" />\n    <Compile Include=\"logic\\fol\\inference\\trace\\FOLTFMResolutiontracer.cs\" />\n    <Compile Include=\"logic\\fol\\kb\\data\\Chain.cs\" />\n    <Compile Include=\"logic\\fol\\kb\\data\\Clause.cs\" />\n    <Compile Include=\"logic\\fol\\kb\\data\\CNF.cs\" />\n    <Compile Include=\"logic\\fol\\kb\\data\\Literal.cs\" />\n    <Compile Include=\"logic\\fol\\kb\\data\\ReducedLiteral.cs\" />\n    <Compile Include=\"logic\\fol\\kb\\FOLKnowledgeBase.cs\" />\n    <Compile Include=\"logic\\fol\\kb\\FOLKnowledgeBaseFactory.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\AbstractFOLVisitor.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\AtomicSentence.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\ConnectedSentence.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\Constant.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\FOLNode.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\Function.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\NotSentence.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\Predicate.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\QuantifiedSentence.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\Sentence.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\Term.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\TermEquality.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\ast\\Variable.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\FOLLexer.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\FOLParser.cs\" />\n    <Compile Include=\"logic\\fol\\parsing\\FOLVisitor.cs\" />\n    <Compile Include=\"logic\\fol\\PredicateCollector.cs\" />\n    <Compile Include=\"logic\\fol\\Quantifiers.cs\" />\n    <Compile Include=\"logic\\fol\\StandardizeApart.cs\" />\n    <Compile Include=\"logic\\fol\\StandardizeApartIndexical.cs\" />\n    <Compile Include=\"logic\\fol\\StandardizeApartIndexicalFactory.cs\" />\n    <Compile Include=\"logic\\fol\\StandardizeApartInPlace.cs\" />\n    <Compile Include=\"logic\\fol\\StandardizeApartResult.cs\" />\n    <Compile Include=\"logic\\fol\\SubstVisitor.cs\" />\n    <Compile Include=\"logic\\fol\\SubsumptionElimination.cs\" />\n    <Compile Include=\"logic\\fol\\Unifier.cs\" />\n    <Compile Include=\"logic\\fol\\VariableCollector.cs\" />\n    <Compile Include=\"logic\\propositional\\agent\\KBAgent.cs\" />\n    <Compile Include=\"logic\\propositional\\kb\\KnowledgeBase.cs\" />\n    <Compile Include=\"logic\\propositional\\parsing\\ast\\AtomicSentence.cs\" />\n    <Compile Include=\"logic\\propositional\\parsing\\ast\\ComplexSentence.cs\" />\n    <Compile Include=\"logic\\propositional\\parsing\\ast\\Connective.cs\" />\n    <Compile Include=\"logic\\propositional\\parsing\\ast\\PropositionSymbol.cs\" />\n    <Compile Include=\"logic\\propositional\\parsing\\ast\\Sentence.cs\" />\n    <Compile Include=\"logic\\propositional\\parsing\\PLVisitor.cs\" />\n    <Compile Include=\"Program.cs\" />\n    <Compile Include=\"Properties\\AssemblyInfo.cs\" />\n    <Compile Include=\"search\\framework\\CutOffIndicatorAction.cs\" />\n    <Compile Include=\"search\\framework\\EvaluationFunction.cs\" />\n    <Compile Include=\"search\\framework\\HeuristicFunction.cs\" />\n    <Compile Include=\"search\\framework\\Metrics.cs\" />\n    <Compile Include=\"search\\framework\\Node.cs\" />\n    <Compile Include=\"search\\framework\\NodeExpander.cs\" />\n    <Compile Include=\"search\\framework\\PathCostFunction.cs\" />\n    <Compile Include=\"search\\framework\\PerceptToStateFunction.cs\" />\n    <Compile Include=\"search\\framework\\problem\\ActionsFunction.cs\" />\n    <Compile Include=\"search\\framework\\problem\\BidirectionalProblem.cs\" />\n    <Compile Include=\"search\\framework\\problem\\DefaultGoalTest.cs\" />\n    <Compile Include=\"search\\framework\\problem\\DefaultStepCostFunction.cs\" />\n    <Compile Include=\"search\\framework\\problem\\GoalTest.cs\" />\n    <Compile Include=\"search\\framework\\problem\\Problem.cs\" />\n    <Compile Include=\"search\\framework\\problem\\ResultFunction.cs\" />\n    <Compile Include=\"search\\framework\\problem\\StepCostFunction.cs\" />\n    <Compile Include=\"search\\framework\\qsearch\\GraphSearch.cs\" />\n    <Compile Include=\"search\\framework\\qsearch\\GraphSearchBFS.cs\" />\n    <Compile Include=\"search\\framework\\qsearch\\QueueSearch.cs\" />\n    <Compile Include=\"search\\framework\\qsearch\\TreeSearch.cs\" />\n    <Compile Include=\"search\\framework\\Search.cs\" />\n    <Compile Include=\"search\\framework\\SearchAgent.cs\" />\n    <Compile Include=\"search\\framework\\SearchForActions.cs\" />\n    <Compile Include=\"search\\framework\\SearchUtils.cs\" />\n    <Compile Include=\"search\\framework\\SimpleProblemSolvingAgent.cs\" />\n    <Compile Include=\"search\\framework\\SolutionChecker.cs\" />\n    <Compile Include=\"search\\Local\\FitnessFunction.cs\" />\n    <Compile Include=\"search\\Local\\Individual.cs\" />\n    <Compile Include=\"search\\Local\\Scheduler.cs\" />\n    <Compile Include=\"search\\online\\LRTAStarAgent.cs\" />\n    <Compile Include=\"search\\online\\OnlineDFSAgent.cs\" />\n    <Compile Include=\"search\\online\\OnlineSearchProblem.cs\" />\n    <Compile Include=\"util\\ArrayIterator.cs\" />\n    <Compile Include=\"util\\CSharpRandomizer.cs\" />\n    <Compile Include=\"util\\DisjointSets.cs\" />\n    <Compile Include=\"util\\FrequencyCounter.cs\" />\n    <Compile Include=\"util\\Interval.cs\" />\n    <Compile Include=\"util\\LabeledGraph.cs\" />\n    <Compile Include=\"util\\LinkedHashSet.cs\" />\n    <Compile Include=\"util\\LUDecomposition.cs\" />\n    <Compile Include=\"util\\Matrix.cs\" />\n    <Compile Include=\"util\\MixedRadixNumber.cs\" />\n    <Compile Include=\"util\\MockRandomizer.cs\" />\n    <Compile Include=\"util\\Pair.cs\" />\n    <Compile Include=\"util\\Point2D.cs\" />\n    <Compile Include=\"util\\Randomizer.cs\" />\n    <Compile Include=\"util\\SetOps.cs\" />\n    <Compile Include=\"util\\Table.cs\" />\n    <Compile Include=\"util\\Triplet.cs\" />\n    <Compile Include=\"util\\TwoKeyHashMap.cs\" />\n    <Compile Include=\"util\\Util.cs\" />\n    <Compile Include=\"util\\Vector.cs\" />\n    <Compile Include=\"util\\XYLocation.cs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"App.config\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Folder Include=\"environment\\wumpusworld\\action\\\" />\n  </ItemGroup>\n  <Import Project=\"$(MSBuildToolsPath)\\Microsoft.CSharp.targets\" />\n  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \n       Other similar extension points exist, see Microsoft.Common.targets.\n  <Target Name=\"BeforeBuild\">\n  </Target>\n  <Target Name=\"AfterBuild\">\n  </Target>\n  -->\n</Project>"
  },
  {
    "path": "aima-csharp/environment/cellworld/Cell.cs",
    "content": "using System;\n\nnamespace aima.core.environment.cellworld\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 645.<br>\n     * <br>\n     * A representation of a Cell in the environment detailed in Figure 17.1.\n     * \n     * @param <C>\n     *            the content type of the cell.\n     * \n     * @author Ciaran O'Reilly\n     * @author Ravi Mohan\n     */\n    public class Cell<C>\n    {\n\tprivate int x = 1;\n\tprivate int y = 1;\n\tprivate C content = default(C);\n\n\t/**\n\t * Construct a Cell.\n\t * \n\t * @param x\n\t *            the x position of the cell.\n\t * @param y\n\t *            the y position of the cell.\n\t * @param content\n\t *            the initial content of the cell.\n\t */\n\tpublic Cell(int x, int y, C content)\n\t{\n\t    this.x = x;\n\t    this.y = y;\n\t    this.content = content;\n\t}\n\n\t/**\n\t * \n\t * @return the x position of the cell.\n\t */\n\tpublic int getX()\n\t{\n\t    return x;\n\t}\n\n\t/**\n\t * \n\t * @return the y position of the cell.\n\t */\n\tpublic int getY()\n\t{\n\t    return y;\n\t}\n\n\t/**\n\t * \n\t * @return the content of the cell.\n\t */\n\tpublic C getContent()\n\t{\n\t    return content;\n\t}\n\n\t/**\n\t * Set the cell's content.\n\t * \n\t * @param content\n\t *            the content to be placed in the cell.\n\t */\n\tpublic void setContent(C content)\n\t{\n\t    this.content = content;\n\t}\n\n\tpublic String toString()\n\t{\n\t    return \"<x=\" + x + \", y=\" + y + \", content=\" + content + \">\";\n\t}\n\t\t\n\tpublic bool equals(Object o)\n\t{\n\t    if (o is Cell<C>) {\n\t\tCell <C> c = (Cell <C>) o;\n\t\treturn x == c.x && y == c.y && content.Equals(c.content);\n\t    }\n\t    return false;\n\t}\n\t\n\tpublic int hashCode()\n\t{\n\t    return x + 23 + y + 31 * content.GetHashCode();\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/cellworld/CellWorld.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.util;\n\nnamespace aima.core.environment.cellworld\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 645.<br>\n     * <br>\n     * \n     * A representation for the environment depicted in figure 17.1.<br>\n     * <br>\n     * <b>Note:<b> the x and y coordinates are always positive integers starting at\n     * 1.<br>\n     * <b>Note:<b> If looking at a rectangle - the coordinate (x=1, y=1) will be the\n     * bottom left hand corner.<br>\n     * \n     * \n     * @param <C>\n     *            the type of content for the Cells in the world.\n     * \n     * @author Ciaran O'Reilly\n     * @author Ravi Mohan\n     */\n    public class CellWorld<C>\n    {\n\tprivate LinkedHashSet<Cell<C>> cells = new LinkedHashSet<Cell<C>>();\n\tprivate Dictionary<int, Dictionary<int, Cell<C>>> cellLookup = new Dictionary<int, Dictionary<int, Cell<C>>>();\n\t/**\n\t * Construct a Cell World with size xDimension * y Dimension cells, all with\n\t * their values set to a default content value.\n\t * \n\t * @param xDimension\n\t *            the size of the x dimension.\n\t * @param yDimension\n\t *            the size of the y dimension.\n\t * \n\t * @param defaultCellContent\n\t *            the default content to assign to each cell created.\n\t */\n\tpublic CellWorld(int xDimension, int yDimension, C defaultCellContent)\n\t{\n\t    for (int x = 1; x <= xDimension; x++)\n\t    {\n\t\tDictionary<int, Cell<C>> xCol = new Dictionary<int, Cell<C>>();\n\t\tfor (int y = 1; y <= yDimension; y++)\n\t\t{\n\t\t    Cell<C> c = new Cell<C>(x, y, defaultCellContent);\n\t\t    cells.Add(c);\n\t\t    xCol[y] = c;\n\t\t}\n\t\tcellLookup[x] = xCol;\n\t    }\n\t}\n\n\t/**\n\t * \n\t * @return all the cells in this world.\n\t */\n\tpublic LinkedHashSet<Cell<C>> getCells()\n\t{\n\t    return cells;\n\t}\n\n\t/**\n\t * Determine what cell would be moved into if the specified action is\n\t * performed in the specified cell. Normally, this will be the cell adjacent\n\t * in the appropriate direction. However, if there is no cell in the\n\t * adjacent direction of the action then the outcome of the action is to\n\t * stay in the same cell as the action was performed in.\n\t * \n\t * @param s\n\t *            the cell location from which the action is to be performed.\n\t * @param a\n\t *            the action to perform (Up, Down, Left, or Right).\n\t * @return the Cell an agent would end up in if they performed the specified\n\t *         action from the specified cell location.\n\t */\n\tpublic Cell<C> result(Cell<C> s, CellWorldAction a)\n\t{\n\t    Cell<C> sDelta = getCellAt(a.getXResult(s.getX()), a.getYResult(s\n\t\t\t    .getY()));\n\t    if (null == sDelta)\n\t    {\n\t\t// Default to no effect\n\t\t// (i.e. bumps back in place as no adjoining cell).\n\t\tsDelta = s;\n\t    }\n\t    return sDelta;\n\t}\n\n\t/**\n\t * Remove the cell at the specified location from this Cell World. This\n\t * allows you to introduce barriers into different location.\n\t * \n\t * @param x\n\t *            the x dimension of the cell to be removed.\n\t * @param y\n\t *            the y dimension of the cell to be removed.\n\t */\n\tpublic void removeCell(int x, int y)\n\t{\n\t    Dictionary<int, Cell<C>> xCol = cellLookup[x];\n\t    if (null != xCol)\n\t    {\n\t\txCol.Remove(y);\n\t\tcells.Remove(xCol[y]);\n\t    }\n\t}\n\n\t/**\n\t * Get the cell at the specified x and y locations.\n\t * \n\t * @param x\n\t *            the x dimension of the cell to be retrieved.\n\t * @param y\n\t *            the y dimension of the cell to be retrieved.\n\t * @return the cell at the specified x,y location, null if no cell exists at\n\t *         this location.\n\t */\n\tpublic Cell<C> getCellAt(int x, int y)\n\t{\n\t    Cell<C> c = null;\n\t    Dictionary<int, Cell<C>> xCol = cellLookup[x];\n\t    if (null != xCol)\n\t    {\n\t\tc = xCol[y];\n\t    }\n\t    return c;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/cellworld/CellWorldAction.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.util;\n\nnamespace aima.core.environment.cellworld\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 645.<br>\n     * <br>\n     * \n     * The actions in every state are Up, Down, Left, and Right.<br>\n     * <br>\n     * <b>Note:<b> Moving 'North' causes y to increase by 1, 'Down' y to decrease by\n     * 1, 'Left' x to decrease by 1, and 'Right' x to increase by 1 within a Cell\n     * World.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n     public class CellWorldAction : Action\n    {\n\tpublic CellWorldAction()\n\t{\n\n\t}\n\n\tpublic CellWorldAction(ActionEnum action)\n\t{\n\t    this._action = action;\n\t}\n\n\n\tpublic enum ActionEnum\n\t{\n\t    Up, Down, Left, Right, None\n\t};\n\n\tprivate ActionEnum _action;\n\n\tprivate static readonly LinkedHashSet<ActionEnum> _actions = new LinkedHashSet<ActionEnum>();\n\n\n\tstatic CellWorldAction()\n\t{\n\t    _actions.Add(ActionEnum.Up);\n\t    _actions.Add(ActionEnum.Down);\n\t    _actions.Add(ActionEnum.Left);\n\t    _actions.Add(ActionEnum.Right);\n\t    _actions.Add(ActionEnum.None);\n\t}\n\n\t/**\n\t * \n\t * @return a set of the actual actions.\n\t */\n\tpublic static LinkedHashSet<ActionEnum> actions()\n\t{\n\t    return _actions;\n\t}\n\n\t// START-Action\n\n\tpublic bool isNoOp()\n\t{\n\t    if (this._action == ActionEnum.None)\n\t    {\n\t\treturn true;\n\t    }\n\t    return false;\n\t}\n\n\t// END-Action\n\t\n\t/**\n\t * \n\t * @param curX\n\t *            the current x position.\n\t * @return the result on the x position of applying this action.\n\t */\n\tpublic int getXResult(int curX)\n\t{\n\t    int newX = curX;\n\n\t    switch (this._action)\n\t    {\n\t\tcase ActionEnum.Left:\n\t\t    newX--;\n\t\t    break;\n\t\tcase ActionEnum.Right:\n\t\t    newX++;\n\t\t    break;\n\t    }\n\t    return newX;\n\t}\n\n\t/**\n\t * \n\t * @param curY\n\t *            the current y position.\n\t * @return the result on the y position of applying this action.\n\t */\n\tpublic int getYResult(int curY)\n\t{\n\t    int newY = curY;\n\n\t    switch (this._action)\n\t    {\n\t\tcase ActionEnum.Up:\n\t\t    newY++;\n\t\t    break;\n\t\tcase ActionEnum.Down:\n\t\t    newY--;\n\t\t    break;\n\t    }\n\t    return newY;\n\t}\n\n\t/**\n\t * \n\t * @return the first right angled action related to this action.\n\t */\n\tpublic ActionEnum getFirstRightAngledAction()\n\t{\n\t    ActionEnum a = ActionEnum.None;\n\n\t    switch (this._action)\n\t    {\n\t\tcase ActionEnum.Up:\n\t\tcase ActionEnum.Down:\n\t\t    a = ActionEnum.Left;\n\t\t    break;\n\t\tcase ActionEnum.Left:\n\t\tcase ActionEnum.Right:\n\t\t    a = ActionEnum.Down;\n\t\t    break;\n\t\tcase ActionEnum.None:\n\t\t    a = ActionEnum.None;\n\t\t    break;\n\t    }\n\t    return a;\n\t}\n\n\t/**\n\t * \n\t * @return the second right angled action related to this action.\n\t */\n\tpublic ActionEnum getSecondRightAngledAction()\n\t{\n\t    ActionEnum a = ActionEnum.None;\n\n\t    switch (this._action)\n\t    {\n\t\tcase ActionEnum.Up:\n\t\tcase ActionEnum.Down:\n\t\t    a = ActionEnum.Right;\n\t\t    break;\n\t\tcase ActionEnum.Left:\n\t\tcase ActionEnum.Right:\n\t\t    a = ActionEnum.Up;\n\t\t    break;\n\t\tcase ActionEnum.None:\n\t\t    a = ActionEnum.None;\n\t\t    break;\n\t    }\n\t    return a;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/cellworld/CellWorldFactory.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.environment.cellworld\n{\n    /**\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n     public class CellWorldFactory\n    {\n\t/**\n\t * Create the cell world as defined in Figure 17.1 in AIMA3e. (a) A simple 4\n\t * x 3 environment that presents the agent with a sequential decision\n\t * problem.\n\t * \n\t * @return a cell world representation of Fig 17.1 in AIMA3e.\n\t */\n\tpublic static CellWorld<Double> createCellWorldForFig17_1()\n\t{\n\t    CellWorld<Double> cw = new CellWorld<Double>(4, 3, -0.04);\n\n\t    cw.removeCell(2, 2);\n\n\t    cw.getCellAt(4, 3).setContent(1.0);\n\t    cw.getCellAt(4, 2).setContent(-1.0);\n\n\t    return cw;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/eightpuzzle/BidirectionalEightPuzzleProblem.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.environment.eightpuzzle\n{\n    /**\n     * @author Ruediger Lunde\n     * \n     */\n    public class BidirectionalEightPuzzleProblem : Problem, BidirectionalProblem\n    {\n\tProblem reverseProblem;\n\n\tpublic BidirectionalEightPuzzleProblem(EightPuzzleBoard initialState): base(initialState, EightPuzzleFunctionFactory.getActionsFunction(),\n\t\t\t\tEightPuzzleFunctionFactory.getResultFunction(),\n\t\t\t\tnew DefaultGoalTest(new EightPuzzleBoard(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 })))\n\t{\n\t    reverseProblem = new Problem(new EightPuzzleBoard(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 }),\n\t\t\t\tEightPuzzleFunctionFactory.getActionsFunction(), EightPuzzleFunctionFactory.getResultFunction(),\n\t\t\t\tnew DefaultGoalTest(initialState));\n\t}\n\n\tpublic Problem getOriginalProblem()\n\t{\n\t    return this;\n\t}\n\n\tpublic Problem getReverseProblem()\n\t{\n\t    return reverseProblem;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/eightpuzzle/EightPuzzleBoard.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.util;\n\nnamespace aima.core.environment.eightpuzzle\n{\n    /**\n     * @author Ravi Mohan\n     * @author R. Lunde\n     */\n    public class EightPuzzleBoard\n    {\n\tpublic static agent.Action LEFT = new DynamicAction(\"Left\");\n\n\tpublic static agent.Action RIGHT = new DynamicAction(\"Right\");\n\n\tpublic static agent.Action UP = new DynamicAction(\"Up\");\n\n\tpublic static agent.Action DOWN = new DynamicAction(\"Down\");\n\n\tprivate int[] state;\n\n\t// PUBLIC METHODS\n\n\tpublic EightPuzzleBoard()\n\t{\n\t    state = new int[] { 5, 4, 0, 6, 1, 8, 7, 3, 2 };\n\t}\n\n\tpublic EightPuzzleBoard(int[] state)\n\t{\n\t    this.state = new int[state.Length];\n\t    System.Array.Copy(state, 0, this.state, 0, state.Length);\n\t}\n\n\tpublic EightPuzzleBoard(EightPuzzleBoard copyBoard): this(copyBoard.getState())\n\t{\n\t    \n\t}\n\n\tpublic int[] getState()\n\t{\n\t    return state;\n\t}\n\n\tpublic int getValueAt(XYLocation loc)\n\t{\n\t    return getValueAt(loc.getXCoOrdinate(), loc.getYCoOrdinate());\n\t}\n\n\tpublic XYLocation getLocationOf(int val)\n\t{\n\t    int absPos = getPositionOf(val);\n\t    return new XYLocation(getXCoord(absPos), getYCoord(absPos));\n\t}\n\n\tpublic void moveGapRight()\n\t{\n\t    int gapPos = getGapPosition();\n\t    int x = getXCoord(gapPos);\n\t    int ypos = getYCoord(gapPos);\n\t    if (!(ypos == 2))\n\t    {\n\t\tint valueOnRight = getValueAt(x, ypos + 1);\n\t\tsetValue(x, ypos, valueOnRight);\n\t\tsetValue(x, ypos + 1, 0);\n\t    }\n\t}\n\n\tpublic void moveGapLeft()\n\t{\n\t    int gapPos = getGapPosition();\n\t    int x = getXCoord(gapPos);\n\t    int ypos = getYCoord(gapPos);\n\t    if (!(ypos == 0))\n\t    {\n\t\tint valueOnLeft = getValueAt(x, ypos - 1);\n\t\tsetValue(x, ypos, valueOnLeft);\n\t\tsetValue(x, ypos - 1, 0);\n\t    }\n\t}\n\n\tpublic void moveGapDown()\n\t{\n\t    int gapPos = getGapPosition();\n\t    int x = getXCoord(gapPos);\n\t    int y = getYCoord(gapPos);\n\t    if (!(x == 2))\n\t    {\n\t\tint valueOnBottom = getValueAt(x + 1, y);\n\t\tsetValue(x, y, valueOnBottom);\n\t\tsetValue(x + 1, y, 0);\n\t    }\n\t}\n\n\tpublic void moveGapUp()\n\t{\n\t    int gapPos = getGapPosition();\n\t    int x = getXCoord(gapPos);\n\t    int y = getYCoord(gapPos);\n\t    if (!(x == 0))\n\t    {\n\t\tint valueOnTop = getValueAt(x - 1, y);\n\t\tsetValue(x, y, valueOnTop);\n\t\tsetValue(x - 1, y, 0);\n\t    }\n\t}\n\n\tpublic List<XYLocation> getPositions()\n\t{\n\t    List<XYLocation> retVal = new List<XYLocation>();\n\t    for (int i = 0; i < 9; i++)\n\t    {\n\t\tint absPos = getPositionOf(i);\n\t\tXYLocation loc = new XYLocation(getXCoord(absPos),\n\t\t\t\tgetYCoord(absPos));\n\t\tretVal.Add(loc);\n\n\t    }\n\t    return retVal;\n\t}\n\n\tpublic void setBoard(List<XYLocation> locs)\n\t{\n\t    int count = 0;\n\t    for (int i = 0; i < locs.Capacity; i++)\n\t    {\n\t\tXYLocation loc = locs[i];\n\t\tthis.setValue(loc.getXCoOrdinate(), loc.getYCoOrdinate(), count);\n\t\tcount = count + 1;\n\t    }\n\t}\n\n\tpublic bool canMoveGap(agent.Action where)\n\t{\n\t    bool retVal = true;\n\t    int absPos = getPositionOf(0);\n\t    if (where.Equals(LEFT))\n\t\tretVal = (getYCoord(absPos) != 0);\n\t    else if (where.Equals(RIGHT))\n\t\tretVal = (getYCoord(absPos) != 2);\n\t    else if (where.Equals(UP))\n\t\tretVal = (getXCoord(absPos) != 0);\n\t    else if (where.Equals(DOWN))\n\t\tretVal = (getXCoord(absPos) != 2);\n\t    return retVal;\n\t}\n\n\tpublic bool equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if ((o == null) || (this.GetType() != o.GetType()))\n\t    {\n\t\treturn false;\n\t    }\n\t    EightPuzzleBoard aBoard = (EightPuzzleBoard)o;\n\n\t    for (int i = 0; i < 8; i++)\n\t    {\n\t\tif (this.getPositionOf(i) != aBoard.getPositionOf(i))\n\t\t{\n\t\t    return false;\n\t\t}\n\t    }\n\t    return true;\n\t}\n\t\n\tpublic int hashCode()\n\t{\n\t    int result = 17;\n\t    for (int i = 0; i < 8; i++)\n\t    {\n\t\tint position = this.getPositionOf(i);\n\t\tresult = 37 * result + position;\n\t    }\n\t    return result;\n\t}\n\t\t\n\tpublic String toString()\n\t{\n\t    String retVal = state[0] + \" \" + state[1] + \" \" + state[2] + \"\\n\"\n\t\t\t    + state[3] + \" \" + state[4] + \" \" + state[5] + \" \" + \"\\n\"\n\t\t\t    + state[6] + \" \" + state[7] + \" \" + state[8];\n\t    return retVal;\n\t}\n\n\t// PRIVATE METHODS\n\n\t/**\n\t * Note: The graphic representation maps x values on row numbers (x-axis in\n\t * vertical direction).\n\t */\n\tprivate int getXCoord(int absPos)\n\t{\n\t    return absPos / 3;\n\t}\n\n\t/**\n\t * Note: The graphic representation maps y values on column numbers (y-axis\n\t * in horizontal direction).\n\t */\n\tprivate int getYCoord(int absPos)\n\t{\n\t    return absPos % 3;\n\t}\n\n\tprivate int getAbsPosition(int x, int y)\n\t{\n\t    return x * 3 + y;\n\t}\n\n\tprivate int getValueAt(int x, int y)\n\t{\n\t    // refactor this use either case or a div/mod soln\n\t    return state[getAbsPosition(x, y)];\n\t}\n\n\tprivate int getGapPosition()\n\t{\n\t    return getPositionOf(0);\n\t}\n\n\tprivate int getPositionOf(int val)\n\t{\n\t    int retVal = -1;\n\t    for (int i = 0; i < 9; i++)\n\t    {\n\t\tif (state[i] == val)\n\t\t{\n\t\t    retVal = i;\n\t\t}\n\t    }\n\t    return retVal;\n\t}\n\n\tprivate void setValue(int x, int y, int val)\n\t{\n\t    int absPos = getAbsPosition(x, y);\n\t    state[absPos] = val;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/eightpuzzle/EightPuzzleFunctionFactory.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.search.framework.problem;\nusing aima.core.util;\n\nnamespace aima.core.environment.eightpuzzle\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class EightPuzzleFunctionFactory\n    {\n\tprivate static ActionsFunction _actionsFunction = null;\n\tprivate static ResultFunction _resultFunction = null;\n\n\tpublic static ActionsFunction getActionsFunction()\n\t{\n\t    if (null == _actionsFunction)\n\t    {\n\t\t_actionsFunction = new EPActionsFunction();\n\t    }\n\t    return _actionsFunction;\n\t}\n\n\tpublic static ResultFunction getResultFunction()\n\t{\n\t    if (null == _resultFunction)\n\t    {\n\t\t_resultFunction = new EPResultFunction();\n\t    }\n\t    return _resultFunction;\n\t}\n\n\tprivate class EPActionsFunction : ActionsFunction\n\t{\n\t    public HashSet<Action> actions(System.Object state)\n\t    {\n\t\tEightPuzzleBoard board = (EightPuzzleBoard)state;\n\n\t\tHashSet<Action> actions = new HashSet<Action>();\n\n\t\tif (board.canMoveGap(EightPuzzleBoard.UP))\n\t\t{\n\t\t    actions.Add(EightPuzzleBoard.UP);\n\t\t}\n\t\tif (board.canMoveGap(EightPuzzleBoard.DOWN))\n\t\t{\n\t\t    actions.Add(EightPuzzleBoard.DOWN);\n\t\t}\n\t\tif (board.canMoveGap(EightPuzzleBoard.LEFT))\n\t\t{\n\t\t    actions.Add(EightPuzzleBoard.LEFT);\n\t\t}\n\t\tif (board.canMoveGap(EightPuzzleBoard.RIGHT))\n\t\t{\n\t\t    actions.Add(EightPuzzleBoard.RIGHT);\n\t\t}\n\n\t\treturn actions;\n\t    }\n\t}\n\n\tprivate class EPResultFunction : ResultFunction\n\t{\n\t    public System.Object result(System.Object s, Action a)\n\t    {\n\t\tEightPuzzleBoard board = (EightPuzzleBoard) s;\n\n\t\tif (EightPuzzleBoard.UP.Equals(a)\n\t\t\t&& board.canMoveGap(EightPuzzleBoard.UP))\n\t\t{\n\t\t    EightPuzzleBoard newBoard = new EightPuzzleBoard(board);\n\t\t    newBoard.moveGapUp();\n\t\t    return newBoard;\n\t\t}\n\t\telse if (EightPuzzleBoard.DOWN.Equals(a)\n\t\t      && board.canMoveGap(EightPuzzleBoard.DOWN))\n\t\t{\n\t\t    EightPuzzleBoard newBoard = new EightPuzzleBoard(board);\n\t\t    newBoard.moveGapDown();\n\t\t    return newBoard;\n\t\t}\n\t\telse if (EightPuzzleBoard.LEFT.Equals(a)\n\t\t      && board.canMoveGap(EightPuzzleBoard.LEFT))\n\t\t{\n\t\t    EightPuzzleBoard newBoard = new EightPuzzleBoard(board);\n\t\t    newBoard.moveGapLeft();\n\t\t    return newBoard;\n\t\t}\n\t\telse if (EightPuzzleBoard.RIGHT.Equals(a)\n\t\t      && board.canMoveGap(EightPuzzleBoard.RIGHT))\n\t\t{\n\t\t    EightPuzzleBoard newBoard = new EightPuzzleBoard(board);\n\t\t    newBoard.moveGapRight();\n\t\t    return newBoard;\n\t\t}\n\n\t\t// The Action is not understood or is a NoOp\n\t\t// the result will be the current state.\n\t\treturn s;\n\t    }\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/eightpuzzle/EightPuzzleGoalTest.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.environment.eightpuzzle\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public class EightPuzzleGoalTest : GoalTest\n    {\n\tEightPuzzleBoard goal = new EightPuzzleBoard(new int[] { 0, 1, 2, 3, 4, 5,\n\t\t\t6, 7, 8 });\n\n\tpublic bool isGoalState(Object state)\n\t{\n\t    EightPuzzleBoard board = (EightPuzzleBoard)state;\n\t    return board.Equals(goal);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/eightpuzzle/ManhattanHeuristicFunction.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.search.framework;\nusing aima.core.util;\n\nnamespace aima.core.environment.eightpuzzle\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public class ManhattanHeuristicFunction : HeuristicFunction\n    {\n\tpublic double h(Object state)\n\t{\n\t    EightPuzzleBoard board = (EightPuzzleBoard)state;\n\t    int retVal = 0;\n\t    for (int i = 1; i < 9; i++)\n\t    {\n\t\tXYLocation loc = board.getLocationOf(i);\n\t\tretVal += evaluateManhattanDistanceOf(i, loc);\n\t    }\n\t    return retVal;\n\t}\n\n\tpublic int evaluateManhattanDistanceOf(int i, XYLocation loc)\n\t{\n\t    int retVal = -1;\n\t    int xpos = loc.getXCoOrdinate();\n\t    int ypos = loc.getYCoOrdinate();\n\t    switch (i)\n\t    {\n\n\t\tcase 1:\n\t\t    retVal = Math.Abs(xpos - 0) + Math.Abs(ypos - 1);\n\t\t    break;\n\t\tcase 2:\n\t\t    retVal = Math.Abs(xpos - 0) + Math.Abs(ypos - 2);\n\t\t    break;\n\t\tcase 3:\n\t\t    retVal = Math.Abs(xpos - 1) + Math.Abs(ypos - 0);\n\t\t    break;\n\t\tcase 4:\n\t\t    retVal = Math.Abs(xpos - 1) + Math.Abs(ypos - 1);\n\t\t    break;\n\t\tcase 5:\n\t\t    retVal = Math.Abs(xpos - 1) + Math.Abs(ypos - 2);\n\t\t    break;\n\t\tcase 6:\n\t\t    retVal = Math.Abs(xpos - 2) + Math.Abs(ypos - 0);\n\t\t    break;\n\t\tcase 7:\n\t\t    retVal = Math.Abs(xpos - 2) + Math.Abs(ypos - 1);\n\t\t    break;\n\t\tcase 8:\n\t\t    retVal = Math.Abs(xpos - 2) + Math.Abs(ypos - 2);\n\t\t    break;\n\n\t    }\n\t    return retVal;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/eightpuzzle/MisplacedTilleHeuristicFunction.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.search.framework;\nusing aima.core.util;\n\nnamespace aima.core.environment.eightpuzzle\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public class MisplacedTilleHeuristicFunction : HeuristicFunction\n    {\n\tpublic double h(Object state)\n\t{\n\t    EightPuzzleBoard board = (EightPuzzleBoard)state;\n\t    return getNumberOfMisplacedTiles(board);\n\t}\n\n\tprivate int getNumberOfMisplacedTiles(EightPuzzleBoard board)\n\t{\n\t    int numberOfMisplacedTiles = 0;\n\t    if (!(board.getLocationOf(0).Equals(new XYLocation(0, 0))))\n\t    {\n\t\tnumberOfMisplacedTiles++;\n\t    }\n\t    if (!(board.getLocationOf(1).Equals(new XYLocation(0, 1))))\n\t    {\n\t\tnumberOfMisplacedTiles++;\n\t    }\n\t    if (!(board.getLocationOf(2).Equals(new XYLocation(0, 2))))\n\t    {\n\t\tnumberOfMisplacedTiles++;\n\t    }\n\t    if (!(board.getLocationOf(3).Equals(new XYLocation(1, 0))))\n\t    {\n\t\tnumberOfMisplacedTiles++;\n\t    }\n\t    if (!(board.getLocationOf(4).Equals(new XYLocation(1, 1))))\n\t    {\n\t\tnumberOfMisplacedTiles++;\n\t    }\n\t    if (!(board.getLocationOf(5).Equals(new XYLocation(1, 2))))\n\t    {\n\t\tnumberOfMisplacedTiles++;\n\t    }\n\t    if (!(board.getLocationOf(6).Equals(new XYLocation(2, 0))))\n\t    {\n\t\tnumberOfMisplacedTiles++;\n\t    }\n\t    if (!(board.getLocationOf(7).Equals(new XYLocation(2, 1))))\n\t    {\n\t\tnumberOfMisplacedTiles++;\n\t    }\n\t    if (!(board.getLocationOf(8).Equals(new XYLocation(2, 2))))\n\t    {\n\t\tnumberOfMisplacedTiles++;\n\t    }\n\t    return numberOfMisplacedTiles;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/AdaptableHeuristicFunction.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.search.framework;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * This class extends heuristic functions in two ways: It maintains a goal and a\n     * map to estimate distance to goal for states in route planning problems, and\n     * it provides a method to adapt to different goals.\n     * \n     * @author Ruediger Lunde\n     */\n    public abstract class AdaptableHeuristicFunction\n    {\n\t/** The Current Goal. */\n\tprotected Object goal;\n\t/** The map to be used for distance to goal estimates. */\n\tprotected Map map;\n\n\t/**\n\t * Modifies goal and map information and returns the modified heuristic\n\t * function.\n\t */\n\tpublic AdaptableHeuristicFunction adaptToGoal(Object goal, Map map)\n\t{\n\t    this.goal = goal;\n\t    this.map = map;\n\t    return this;\n\t}\n\n\t// when subclassing: Don't forget to implement the most important method\n\t// public double h(Object state)\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/BidirectionalMapProblem.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class BidirectionalMapProblem : Problem, BidirectionalProblem\n    {\n\tMap map;\n\n\tProblem reverseProblem;\n\n\tpublic BidirectionalMapProblem(Map map, String initialState, String goalState): this(map, initialState, goalState, new DefaultGoalTest(goalState))\n\t{\n\t    \n\t}\n\n\tpublic BidirectionalMapProblem(Map map, String initialState, String goalState, GoalTest goalTest) :  base(initialState, MapFunctionFactory.getActionsFunction(map), MapFunctionFactory.getResultFunction(),\n\t\t\t    goalTest, new MapStepCostFunction(map))\n\t{ \n\t    this.map = map;\n\n\t    reverseProblem = new Problem(goalState, MapFunctionFactory.getReverseActionsFunction(map),\n\t\t\t    MapFunctionFactory.getResultFunction(), new DefaultGoalTest(initialState),\n\t\t\t    new MapStepCostFunction(map));\n\t}\n\n\t// START Interface BidrectionalProblem\n\tpublic Problem getOriginalProblem()\n\t{\n\t    return this;\n\t}\n\n\tpublic Problem getReverseProblem()\n\t{\n\t    return reverseProblem;\n\t}\n\t// END Interface BirectionalProblem\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/DynAttributeNames.cs",
    "content": "using System;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * The AIMA framework uses dynamic attributes to make implementations of agents\n     * and environments completely independent of each other. The disadvantage of\n     * this concept is, that it's error-prone. This set of constants is designed to\n     * make information exchange more reliable for map agents. Two kinds of\n     * attributes are distinguished. Percept attributes are attached to percepts.\n     * They are generated by the environment and read by by the agent.\n     * EnvironmentState attributes are attached to the EnvironmentState of the\n     * Environment.\n     * \n     * @author Ruediger Lunde\n     */\n    public class DynAttributeNames\n    {\n\t/**\n\t * Name of a dynamic attribute, which contains the current location of the\n\t * agent. Expected value type: String.\n\t */\n\tpublic static readonly String AGENT_LOCATION = \"location\";\n\t/**\n\t * Name of a dynamic attribute, which tells the agent where it is. Expected\n\t * value type: String.\n\t */\n\tpublic static readonly String PERCEPT_IN = \"in\";\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/ExtendableMap.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.util;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * Implements a map with locations, distance labeled links between the\n     * locations, straight line distances, and 2d-placement positions of locations.\n     * Locations are represented by strings and travel distances by double values.\n     * Locations and links can be added dynamically and removed after creation. This\n     * enables to read maps from file or to modify them with respect to newly\n     * obtained knowledge.\n     * \n     * @author Ruediger Lunde\n     */\n    public class ExtendableMap : Map\n    {\n\t/**\n\t * Stores map data. Locations are represented as vertices and connections\n\t * (links) as directed edges labeled with corresponding travel distances.\n\t */\n\tprivate readonly LabeledGraph<String, Double> links;\n\n\t/** Stores xy-coordinates for each location. */\n\tprivate readonly Dictionary<String, Point2D> locationPositions;\n\n\t/** Creates an empty map. */\n\tpublic ExtendableMap()\n\t{\n\t    links = new LabeledGraph<String, Double>();\n\t    locationPositions = new Dictionary<String, Point2D>();\n\t}\n\n\t/** Removes everything. */\n\tpublic void clear()\n\t{\n\t    links.clear();\n\t    locationPositions.Clear();\n\t}\n\n\t/** Clears all connections but keeps location position informations. */\n\tpublic void clearLinks()\n\t{\n\t    links.clear();\n\t}\n\n\t/** Returns a list of all locations. */\n\tpublic List<String> getLocations()\n\t{\n\t    return links.getVertexLabels();\n\t}\n\n\t/** Checks whether the given string is the name of a location. */\n\tpublic bool isLocation(String str)\n\t{\n\t    return links.isVertexLabel(str);\n\t}\n\n\t/**\n\t * Answers to the question: Where can I get, following one of the\n\t * connections starting at the specified location?\n\t */\n\tpublic List<String> getPossibleNextLocations(String location)\n\t{\n\t    List<String> result = links.getSuccessors(location);\n\t    result.Sort();\n\t    return result;\n\t}\n\n\t/**\n\t * Answers to the question: From where can I reach a specified location,\n\t * following one of the map connections? This implementation just calls\n\t * {@link #getPossibleNextLocations(String)} as the underlying graph structure\n\t * cannot be traversed efficiently in reverse order.\n\t */\n\tpublic List<String> getPossiblePrevLocations(String location)\n\t{\n\t    return getPossibleNextLocations(location);\n\t}\n\n\t/**\n\t * Returns the travel distance between the two specified locations if they\n\t * are linked by a connection and null otherwise.\n\t */\n\tpublic Double getDistance(String fromLocation, String toLocation)\n\t{\n\t    return links.get(fromLocation, toLocation);\n\t}\n\n\t/** Adds a one-way connection to the map. */\n\tpublic void addUnidirectionalLink(String fromLocation, String toLocation, Double distance)\n\t{\n\t    links.set(fromLocation, toLocation, distance);\n\t}\n\n\t/**\n\t * Adds a connection which can be traveled in both direction. Internally,\n\t * such a connection is represented as two one-way connections.\n\t */\n\tpublic void addBidirectionalLink(String fromLocation, String toLocation, Double distance)\n\t{\n\t    links.set(fromLocation, toLocation, distance);\n\t    links.set(toLocation, fromLocation, distance);\n\t}\n\n\t/**\n\t * Returns a location which is selected by random.\n\t */\n\tpublic String randomlyGenerateDestination()\n\t{\n\t    return Util.selectRandomlyFromList(getLocations());\n\t}\n\n\t/** Removes a one-way connection. */\n\tpublic void removeUnidirectionalLink(String fromLocation, String toLocation)\n\t{\n\t    links.remove(fromLocation, toLocation);\n\t}\n\n\t/** Removes the two corresponding one-way connections. */\n\tpublic void removeBidirectionalLink(String fromLocation, String toLocation)\n\t{\n\t    links.remove(fromLocation, toLocation);\n\t    links.remove(toLocation, fromLocation);\n\t}\n\n\t/**\n\t * Defines the position of a location as with respect to an orthogonal\n\t * coordinate system.\n\t */\n\tpublic void setPosition(String loc, double x, double y)\n\t{\n\t    locationPositions.Add(loc, new Point2D(x, y));\n\t}\n\n\t/**\n\t * Defines the position of a location within the map.Using this method, one\n\t * location should be selected as reference position (<code>dist= 0 </ code >\n\t *and < code > dir = 0 </ code >) and all the other location should be placed\n\t * relative to it.\n\t * \n\t * @param loc\n\t *            location name\n\t * @param dist\n\t *            distance to a reference position\n\t * @param dir\n\t *            bearing (compass direction) in which the location is seen from\n\t *            the reference position\n\t */\n\tpublic void setDistAndDirToRefLocation(String loc, double dist, int dir)\n\t{\n\t    Point2D coords = new Point2D(-Math.Sin(dir * Math.PI / 180.0) * dist, Math.Cos(dir * Math.PI / 180.0) * dist);\n\t    links.addVertex(loc);\n\t    locationPositions.Add(loc, coords);\n\t}\n\n\t/**\n\t * Returns the position of the specified location as with respect to an\n\t * orthogonal coordinate system.\n\t */\n\tpublic Point2D getPosition(String loc)\n\t{\n\t    return locationPositions[loc];\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/Map.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.util;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * Provides a general interface for maps.\n     * \n     * @author Ruediger Lunde\n     */\n    public interface Map\n    {\n\t/** Returns a list of all locations. */\n\tList<String> getLocations();\n\n\t/**\n\t * Answers to the question: Where can I get, following one of the\n\t * connections starting at the specified location?\n\t */\n\tList<String> getPossibleNextLocations(String location);\n\n\t/**\n\t * Answers to the question: From where can I reach a specified location,\n\t * following one of the map connections?\n\t */\n\tList<String> getPossiblePrevLocations(String location);\n\n\t/**\n\t * Returns the travel distance between the two specified locations if they\n\t * are linked by a connection and null otherwise.\n\t */\n\tDouble getDistance(String fromLocation, String toLocation);\n\n\t/**\n\t * Returns the position of the specified location. The position is\n\t * represented by two coordinates, e.g. latitude and longitude values.\n\t */\n\tPoint2D getPosition(String loc);\n\n\t/**\n\t * Returns a location which is selected by random.\n\t */\n\tString randomlyGenerateDestination();\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/MapAgent.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.search.framework;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class MapAgent : SimpleProblemSolvingAgent\n    {\n\tprotected Map map = null;\n\tprotected DynamicState state = new DynamicState();\n\n\tprivate EnvironmentViewNotifier notifier = null;\n\tprivate Search _search = null;\n\tprivate String[] goals = null;\n\tprivate int goalTestPos = 0;\n\n\tpublic MapAgent(Map map, EnvironmentViewNotifier notifier, Search search)\n\t{\n\t    this.map = map;\n\t    this.notifier = notifier;\n\t    this._search = search;\n\t}\n\n\tpublic MapAgent(Map map, EnvironmentViewNotifier notifier, Search search,\n\t\t\tint maxGoalsToFormulate): base(maxGoalsToFormulate)\n\t{\t    \n\t    this.map = map;\n\t    this.notifier = notifier;\n\t    this._search = search;\n\t}\n\n\tpublic MapAgent(Map map, EnvironmentViewNotifier notifier, Search search,\n\t\t\tString[] goals): base(goals.Length)\n\t{\t    \n\t    this.map = map;\n\t    this.notifier = notifier;\n\t    this._search = search;\n\t    this.goals = new String[goals.Length];\n\t    Array.Copy(goals, 0, this.goals, 0, goals.Length);\n\t}\n\n\t// PROTECTED METHODS\n\t\n\tprotected override State updateState(Percept p)\n\t{\n\t    DynamicPercept dp = (DynamicPercept)p;\n\n\t    state.setAttribute(DynAttributeNames.AGENT_LOCATION,\n\t\t\t    dp.getAttribute(DynAttributeNames.PERCEPT_IN));\n\t    return state;\n\t}\n\n\tprotected override Object formulateGoal()\n\t{\n\t    Object goal = null;\n\t    if (null == goals)\n\t    {\n\t\tgoal = map.randomlyGenerateDestination();\n\t    }\n\t    else\n\t    {\n\t\tgoal = goals[goalTestPos];\n\t\tgoalTestPos++;\n\t    }\n\t    notifier.notifyViews(\"CurrentLocation=In(\"\n\t\t\t    + state.getAttribute(DynAttributeNames.AGENT_LOCATION)\n\t\t\t    + \"), Goal=In(\" + goal + \")\");\n\t    return goal;\n\t}\n\n\tprotected override Problem formulateProblem(Object goal)\n\t{\n\t    return new BidirectionalMapProblem(map,\n\t\t\t    (String)state.getAttribute(DynAttributeNames.AGENT_LOCATION),\n\t\t\t    (String)goal);\n\t}\n\t\n\tprotected override List<agent.Action> search(Problem problem)\n\t{\n\t    List<agent.Action> actions = new List<agent.Action>();\n\t    try\n\t    {\n\t\tList<agent.Action> sactions = _search.search(problem);\n\t\tforeach (agent.Action action in sactions)\n\t\t{\n\t\t    actions.Add(action);\n\t\t}\n\t    }\n\t    catch (Exception ex)\n\t    {\n\t\tSystem.Diagnostics.Debug.WriteLine(ex.ToString());\n\t    }\n\t    return actions;\n\t}\n\n\tprotected override void notifyViewOfMetrics()\n\t{\n\t    HashSet<String> keys = _search.getMetrics().keySet();\n\t    foreach (String key in keys)\n\t    {\n\t\tnotifier.notifyViews(\"METRIC[\" + key + \"]=\"\n\t\t\t\t+ _search.getMetrics().get(key));\n\t    }\n\t}\n\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/MapEnvironment.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * Represents the environment a MapAgent can navigate.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class MapEnvironment : AbstractEnvironment\n    {\n\tprivate Map map = null;\n\tprivate MapEnvironmentState state = new MapEnvironmentState();\n\n\tpublic MapEnvironment(Map map)\n\t{\n\t    this.map = map;\n\t}\n\n\tpublic void addAgent(Agent a, string startLocation)\n\t{\n\t    // Ensure the agent state information is tracked before\n\t    // adding to super, as super will notify the registered\n\t    // EnvironmentViews that is was added.\n\t    state.setAgentLocationAndTravelDistance(a, startLocation, 0.0);\n\t    base.addAgent(a);\n\t}\n\n\tpublic string getAgentLocation(Agent a)\n\t{\n\t    return state.getAgentLocation(a);\n\t}\n\n\tpublic double getAgentTravelDistance(Agent a)\n\t{\n\t    return state.getAgentTravelDistance(a);\n\t}\n\n\tpublic override EnvironmentState getCurrentState()\n\t{\n\t    return state;\n\t}\n\n\tpublic override EnvironmentState executeAction(Agent agent, Action a)\n\t{\n\n\t    if (!a.isNoOp())\n\t    {\n\t\tMoveToAction act = (MoveToAction)a;\n\n\t\tstring currLoc = getAgentLocation(agent);\n\t\tdouble distance = map.getDistance(currLoc, act.getToLocation());\n\t\tif (distance != null)\n\t\t{\n\t\t    double currTD = getAgentTravelDistance(agent);\n\t\t    state.setAgentLocationAndTravelDistance(agent,\n\t\t\t\t    act.getToLocation(), currTD + distance);\n\t\t}\n\t    }\n\t    return state;\n\t}\n\n\tpublic override Percept getPerceptSeenBy(Agent anAgent)\n\t{\n\t    return new DynamicPercept(DynAttributeNames.PERCEPT_IN,\n\t\t\t    getAgentLocation(anAgent));\n\t}\n\n\tpublic Map getMap()\n\t{\n\t    return map;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/MapEnvironmentState.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.util;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class MapEnvironmentState : EnvironmentState\n    {\n\tprivate Dictionary<Agent, Pair<string, double>> agentLocationAndTravelDistance = new Dictionary<Agent, Pair<string, double>>();\n\n\tpublic MapEnvironmentState()\n\t{\n\n\t}\n\n\tpublic string getAgentLocation(Agent a)\n\t{\n\t    Pair<string, double> locAndTDistance = agentLocationAndTravelDistance[a];\n\t    if (null == locAndTDistance)\n\t    {\n\t\treturn null;\n\t    }\n\t    return locAndTDistance.getFirst();\n\t}\n\n\tpublic double getAgentTravelDistance(Agent a)\n\t{\n\t    Pair<string, double> locAndTDistance = agentLocationAndTravelDistance[a];\n\t    if (null == locAndTDistance)\n\t    {\n\t\treturn double.MinValue;\n\t    }\n\t    return locAndTDistance.getSecond();\n\t}\n\n\tpublic void setAgentLocationAndTravelDistance(Agent a, string location,\n\t\t\tdouble travelDistance)\n\t{\n\t    agentLocationAndTravelDistance.Add(a, new Pair<string, double>(\n\t\t\t    location, travelDistance));\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/MapFunctionFactory.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.search.framework;\nusing aima.core.search.framework.problem;\nusing aima.core.util;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class MapFunctionFactory\n    {\n\tprivate static ResultFunction resultFunction;\n\tprivate static PerceptToStateFunction perceptToStateFunction;\n\n\tpublic static ActionsFunction getActionsFunction(Map map)\n\t{\n\t    return new MapActionsFunction(map, false);\n\t}\n\n\tpublic static ActionsFunction getReverseActionsFunction(Map map)\n\t{\n\t    return new MapActionsFunction(map, true);\n\t}\n\n\tpublic static ResultFunction getResultFunction()\n\t{\n\t    if (null == resultFunction)\n\t    {\n\t\tresultFunction = new MapResultFunction();\n\t    }\n\t    return resultFunction;\n\t}\n\n\tprivate class MapActionsFunction : ActionsFunction\n\t{\n\t    private Map map = null;\n\t    private bool reverseMode;\n\n\t    public MapActionsFunction(Map map, bool reverseMode)\n\t    {\n\t\tthis.map = map;\n\t\tthis.reverseMode = reverseMode;\n\t    }\n\n\t    public HashSet<Action> actions(System.Object state)\n\t    {\n\t\tHashSet<Action> actions = new HashSet<Action>();\n\t\tSystem.String location = state.ToString();\n\n\t\tList<System.String> linkedLocations = reverseMode ? map.getPossiblePrevLocations(location)\n\t\t\t\t\t: map.getPossibleNextLocations(location);\n\t\tforeach (System.String linkLoc in linkedLocations)\n\t\t{\n\t\t    actions.Add(new MoveToAction(linkLoc));\n\t\t}\n\t\treturn actions;\n\t    }\n\t}\n\n\tpublic static PerceptToStateFunction getPerceptToStateFunction()\n\t{\n\t    if (null == perceptToStateFunction)\n\t    {\n\t\tperceptToStateFunction = new MapPerceptToStateFunction();\n\t    }\n\t    return perceptToStateFunction;\n\t}\n\n\tprivate class MapResultFunction : ResultFunction\n\t{\n\t    public MapResultFunction()\n\t    {\n\t    }\n\n\t    public System.Object result(System.Object s, Action a)\n\t    {\n\n\t\tif (a is MoveToAction)\n\t\t{\n\t\t    MoveToAction mta = (MoveToAction)a;\n\n\t\t    return mta.getToLocation();\n\t\t}\n\n\t\t// The Action is not understood or is a NoOp\n\t\t// the result will be the current state.\n\t\treturn s;\n\t    }\n\t}\n\n\tprivate class MapPerceptToStateFunction :\n\t\tPerceptToStateFunction\n\t{\n\t    public System.Object getState(Percept p)\n\t    {\n\t\treturn ((DynamicPercept)p)\n\t\t\t.getAttribute(DynAttributeNames.PERCEPT_IN);\n\t    }\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/MapStepCostFunction.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * Implementation of StepCostFunction interface that uses the distance between\n     * locations to calculate the cost in addition to a constant cost, so that it\n     * may be used in conjunction with a Uniform-cost search.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class MapStepCostFunction : StepCostFunction\n    {\n\tprivate Map map = null;\n\t\t\n\t// Used by Uniform-cost search to ensure every step is greater than or equal\n\t// to some small positive constant\n\tprivate static double constantCost = 1.0;\n\n\tpublic MapStepCostFunction(Map map)\n\t{\n\t    this.map = map;\n\t}\n\n\t//\n\t// START-StepCostFunction\n\tpublic double c(object fromCurrentState, Action action, object toNextState)\n\t{\n\n\t    string fromLoc = fromCurrentState.ToString();\n\t    string toLoc = toNextState.ToString();\n\n\t    double distance = map.getDistance(fromLoc, toLoc);\n\n\t    if (distance == null || distance <= 0)\n\t    {\n\t\treturn constantCost;\n\t    }\n\n\t    return distance;\n\t}\n\n\t// END-StepCostFunction\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/MoveToAction.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent.impl;\n\nnamespace aima.core.environment.map\n{ \n    public class MoveToAction : DynamicAction\n    {\n\tpublic const String ATTRIBUTE_MOVE_TO_LOCATION = \"location\";\n\n\tpublic MoveToAction(String location) : base(\"moveTo\")\n\t{\n\t    setAttribute(ATTRIBUTE_MOVE_TO_LOCATION, location);\n\t}\n\n\tpublic String getToLocation()\n\t{\n\t    return (String)getAttribute(ATTRIBUTE_MOVE_TO_LOCATION);\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/environment/map/Scenario.cs",
    "content": "using System;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * A scenario specifies an environment, the agent's knowledge about the\n     * environment, and the agents initial location. It can be used to specify\n     * settings for route planning agent applications.\n     * \n     * @author Ruediger Lunde\n     */\n    public class Scenario\n    {\n\t/**\n\t * A map-based environment. Note that the contained map must be of type\n\t * {@link ExtendableMap}.\n\t */\n\tprivate readonly MapEnvironment env;\n\t/** A map reflecting the knowledge of the agent about the environment. */\n\tprivate readonly Map agentMap;\n\t/** Initial location of the agent. */\n\tprivate readonly String initAgentLoc;\n\n\t/**\n\t * Creates a scenario.\n\t * \n\t * @param env\n\t *            a map-based environment. Note that the contained map must be\n\t *            of type {@link ExtendableMap}\n\t * @param agentMap\n\t *            a map reflecting the knowledge of the agent about the\n\t *            environment\n\t * @param agentLoc\n\t *            initial location of the agent\n\t */\n\tpublic Scenario(MapEnvironment env, Map agentMap, String agentLoc)\n\t{\n\t    this.agentMap = agentMap;\n\t    this.env = env;\n\t    this.initAgentLoc = agentLoc;\n\t}\n\n\tpublic MapEnvironment getEnv()\n\t{\n\t    return env;\n\t}\n\n\tpublic Map getEnvMap()\n\t{\n\t    return env.getMap();\n\t}\n\n\tpublic Map getAgentMap()\n\t{\n\t    return agentMap;\n\t}\n\n\tpublic String getInitAgentLocation()\n\t{\n\t    return initAgentLoc;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/SimplifiedRoadMapOfAustralia.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * Represents a simplified road map of Australia. The initialization method is\n     * declared static. So it can also be used to initialize other specialized\n     * subclasses of {@link ExtendableMap} with road map data from Australia. The\n     * data was extracted from a class developed by Felix Knittel.\n     * \n     * @author Ruediger Lunde\n     */\n    public class SimplifiedRoadMapOfAustralia : ExtendableMap\n    {\n\tpublic SimplifiedRoadMapOfAustralia()\n\t{\n\t    initMap(this);\n\t}\n\n\t// Locations\n\tpublic const String ADELAIDE = \"Adelaide\";\n\tpublic const String ALBANY = \"Albany\";\n\tpublic const String ALICE_SPRINGS = \"AliceSprings\";\n\tpublic const String BRISBANE = \"Brisbane\";\n\tpublic const String BROKEN_HILL = \"BrokenHill\";\n\tpublic const String BROOME = \"Broome\";\n\tpublic const String CAIRNS = \"Cairns\";\n\tpublic const String CAMARVON = \"Camarvon\";\n\tpublic const String CANBERRA = \"Canberra\";\n\tpublic const String CHARLEVILLE = \"Charleville\";\n\tpublic const String COOBER_PEDY = \"CooberPedy\";\n\tpublic const String DARWIN = \"Darwin\";\n\tpublic const String DUBBO = \"Dubbo\";\n\tpublic const String ESPERANCE = \"Esperance\";\n\tpublic const String GERALDTON = \"Geraldton\";\n\tpublic const String HALLS_CREEK = \"HallsCreek\";\n\tpublic const String HAY = \"Hay\";\n\tpublic const String KALGOORLIE = \"Kalgoorlie\";\n\tpublic const String KATHERINE = \"Katherine\";\n\tpublic const String LAKES_ENTRANCE = \"LakesEntrance\";\n\tpublic const String LONGREACH = \"Longreach\";\n\tpublic const String MACKAY = \"Mackay\";\n\tpublic const String MELBOURNE = \"Melbourne\";\n\tpublic const String MOUNT_GAMBIER = \"MountGambier\";\n\tpublic const String MT_ISA = \"MtIsa\";\n\tpublic const String NEWCASTLE = \"Newcastle\";\n\tpublic const String NORSEMAN = \"Norseman\";\n\tpublic const String NYNGAN = \"Nyngan\";\n\tpublic const String PERTH = \"Perth\";\n\tpublic const String PORT_AUGUSTA = \"PortAugusta\";\n\tpublic const String PORT_HEDLAND = \"PortHedland\";\n\tpublic const String PORT_LINCOLN = \"PortLincoln\";\n\tpublic const String PORT_MACQUARIE = \"PortMacquarie\";\n\tpublic const String ROCKHAMPTON = \"Rockhampton\";\n\tpublic const String SYDNEY = \"Sydney\";\n\tpublic const String TAMWORTH = \"Tamworth\";\n\tpublic const String TENNANT_CREEK = \"TennantCreek\";\n\tpublic const String TOWNSVILLE = \"Townsville\";\n\tpublic const String WAGGA_WAGGA = \"WaggaWagga\";\n\tpublic const String WARNAMBOOL = \"Warnambool\";\n\tpublic const String WYNDHAM = \"Wyndham\";\n\n\t/**\n         * Initializes a map with a simplified road map of Australia.\n         */\n\tpublic static void initMap(ExtendableMap map)\n\t{\n\t    map.clear();\n\t    // Add links\n\t    // Distances from http://maps.google.com\n\t    map.addBidirectionalLink(PERTH, ALBANY, 417.0);\n\t    map.addBidirectionalLink(PERTH, KALGOORLIE, 593.0);\n\t    map.addBidirectionalLink(PERTH, GERALDTON, 424.0);\n\t    map.addBidirectionalLink(PERTH, PORT_HEDLAND, 1637.0);\n\t    map.addBidirectionalLink(ALBANY, ESPERANCE, 478.0);\n\t    map.addBidirectionalLink(KALGOORLIE, NORSEMAN, 187.0);\n\t    map.addBidirectionalLink(ESPERANCE, NORSEMAN, 204.0);\n\t    map.addBidirectionalLink(NORSEMAN, PORT_AUGUSTA, 1668.0);\n\t    map.addBidirectionalLink(GERALDTON, CAMARVON, 479.0);\n\t    map.addBidirectionalLink(CAMARVON, PORT_HEDLAND, 872.0);\n\t    map.addBidirectionalLink(PORT_HEDLAND, BROOME, 589.0);\n\t    map.addBidirectionalLink(BROOME, HALLS_CREEK, 685.0);\n\t    map.addBidirectionalLink(HALLS_CREEK, WYNDHAM, 370.0);\n\t    map.addBidirectionalLink(HALLS_CREEK, KATHERINE, 874.0);\n\t    map.addBidirectionalLink(WYNDHAM, KATHERINE, 613.0);\n\t    map.addBidirectionalLink(KATHERINE, DARWIN, 317.0);\n\t    map.addBidirectionalLink(KATHERINE, TENNANT_CREEK, 673.0);\n\t    map.addBidirectionalLink(TENNANT_CREEK, MT_ISA, 663.0);\n\t    map.addBidirectionalLink(TENNANT_CREEK, ALICE_SPRINGS, 508.0);\n\t    map.addBidirectionalLink(ALICE_SPRINGS, COOBER_PEDY, 688.0);\n\t    map.addBidirectionalLink(COOBER_PEDY, PORT_AUGUSTA, 539.0);\n\t    map.addBidirectionalLink(MT_ISA, TOWNSVILLE, 918.0);\n\t    map.addBidirectionalLink(TOWNSVILLE, CAIRNS, 346.0);\n\t    map.addBidirectionalLink(MT_ISA, LONGREACH, 647.0);\n\t    map.addBidirectionalLink(TOWNSVILLE, MACKAY, 388.0);\n\t    map.addBidirectionalLink(MACKAY, ROCKHAMPTON, 336.0);\n\t    map.addBidirectionalLink(LONGREACH, ROCKHAMPTON, 687.0);\n\t    map.addBidirectionalLink(ROCKHAMPTON, BRISBANE, 616.0);\n\t    map.addBidirectionalLink(LONGREACH, CHARLEVILLE, 515.0);\n\t    map.addBidirectionalLink(CHARLEVILLE, BRISBANE, 744.0);\n\t    map.addBidirectionalLink(CHARLEVILLE, NYNGAN, 657.0);\n\t    map.addBidirectionalLink(NYNGAN, BROKEN_HILL, 588.0);\n\t    map.addBidirectionalLink(BROKEN_HILL, PORT_AUGUSTA, 415.0);\n\t    map.addBidirectionalLink(NYNGAN, DUBBO, 166.0);\n\t    map.addBidirectionalLink(DUBBO, BRISBANE, 860.0);\n\t    map.addBidirectionalLink(DUBBO, SYDNEY, 466.0);\n\t    map.addBidirectionalLink(BRISBANE, TAMWORTH, 576.0);\n\t    map.addBidirectionalLink(BRISBANE, PORT_MACQUARIE, 555.0);\n\t    map.addBidirectionalLink(PORT_MACQUARIE, NEWCASTLE, 245.0);\n\t    map.addBidirectionalLink(TAMWORTH, NEWCASTLE, 284.0);\n\t    map.addBidirectionalLink(NEWCASTLE, SYDNEY, 159.0);\n\t    map.addBidirectionalLink(SYDNEY, CANBERRA, 287.0);\n\t    map.addBidirectionalLink(CANBERRA, WAGGA_WAGGA, 243.0);\n\t    map.addBidirectionalLink(DUBBO, WAGGA_WAGGA, 400.0);\n\t    map.addBidirectionalLink(SYDNEY, LAKES_ENTRANCE, 706.0);\n\t    map.addBidirectionalLink(LAKES_ENTRANCE, MELBOURNE, 317.0);\n\t    map.addBidirectionalLink(WAGGA_WAGGA, MELBOURNE, 476.0);\n\t    map.addBidirectionalLink(WAGGA_WAGGA, HAY, 269.0);\n\t    map.addBidirectionalLink(MELBOURNE, WARNAMBOOL, 269.0);\n\t    map.addBidirectionalLink(WARNAMBOOL, MOUNT_GAMBIER, 185.0);\n\t    map.addBidirectionalLink(MOUNT_GAMBIER, ADELAIDE, 449.0);\n\t    map.addBidirectionalLink(HAY, ADELAIDE, 655.0);\n\t    map.addBidirectionalLink(PORT_AUGUSTA, ADELAIDE, 306.0);\n\t    map.addBidirectionalLink(MELBOURNE, ADELAIDE, 728.0);\n\t    map.addBidirectionalLink(PORT_AUGUSTA, PORT_LINCOLN, 341.0);\n\n\t    // Locations coordinates\n\t    // Alice Springs is taken as central point with coordinates (0|0)\n\t    // Therefore x and y coordinates refer to Alice Springs. Note that\n\t    // the coordinates are not very precise and partly modified to\n\t    // get a more real shape of Australia.\n\t    map.setPosition(ADELAIDE, 417, 1289);\n\t    map.setPosition(ALBANY, -1559, 1231);\n\t    map.setPosition(ALICE_SPRINGS, 0, 0);\n\t    map.setPosition(BRISBANE, 1882, 415);\n\t    map.setPosition(BROKEN_HILL, 709, 873);\n\t    map.setPosition(BROOME, -1189, -645);\n\t    map.setPosition(CAIRNS, 1211, -791);\n\t    map.setPosition(CAMARVON, -2004, -34);\n\t    map.setPosition(CANBERRA, 1524, 1189);\n\t    map.setPosition(CHARLEVILLE, 1256, 268);\n\t    map.setPosition(COOBER_PEDY, 86, 593);\n\t    map.setPosition(DARWIN, -328, -1237);\n\t    map.setPosition(DUBBO, 1474, 881);\n\t    map.setPosition(ESPERANCE, -1182, 1132);\n\t    map.setPosition(GERALDTON, -1958, 405);\n\t    map.setPosition(HALLS_CREEK, -630, -624);\n\t    map.setPosition(HAY, 985, 1143);\n\t    map.setPosition(KALGOORLIE, -1187, 729);\n\t    map.setPosition(KATHERINE, -183, -1025);\n\t    map.setPosition(LAKES_ENTRANCE, 1412, 1609);\n\t    map.setPosition(LONGREACH, 1057, -49);\n\t    map.setPosition(MACKAY, 1553, -316);\n\t    map.setPosition(MELBOURNE, 1118, 1570);\n\t    map.setPosition(MOUNT_GAMBIER, 602, 1531);\n\t    map.setPosition(MT_ISA, 563, -344);\n\t    map.setPosition(NEWCASTLE, 1841, 979);\n\t    map.setPosition(NORSEMAN, -1162, 881);\n\t    map.setPosition(NYNGAN, 1312, 781);\n\t    map.setPosition(PERTH, -1827, 814);\n\t    map.setPosition(PORT_AUGUSTA, 358, 996);\n\t    map.setPosition(PORT_HEDLAND, -1558, -438);\n\t    map.setPosition(PORT_LINCOLN, 169, 1205);\n\t    map.setPosition(PORT_MACQUARIE, 1884, 849);\n\t    map.setPosition(ROCKHAMPTON, 1693, -59);\n\t    map.setPosition(SYDNEY, 1778, 1079);\n\t    map.setPosition(TAMWORTH, 1752, 722);\n\t    map.setPosition(TENNANT_CREEK, 30, -445);\n\t    map.setPosition(TOWNSVILLE, 1318, -520);\n\t    map.setPosition(WAGGA_WAGGA, 1322, 1125);\n\t    map.setPosition(WARNAMBOOL, 761, 1665);\n\t    map.setPosition(WYNDHAM, -572, -932);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/SimplifiedRoadMapOfPartOfRomania.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * Represents a simplified road map of Romania. The initialization method is\n     * declared static. So it can also be used to initialize other specialized\n     * subclasses of {@link ExtendableMap} with road map data from Romania. Location\n     * names, road distances and directions have been extracted from Artificial\n     * Intelligence A Modern Approach (2nd Edition), Figure 3.2, page 63. The\n     * straight-line distances to Bucharest have been taken from Artificial\n     * Intelligence A Modern Approach (2nd Edition), Figure 4.1, page 95.\n     * \n     * @author Ruediger Lunde\n     */\n    public class SimplifiedRoadMapOfPartOfRomania : ExtendableMap\n    {\n\tpublic SimplifiedRoadMapOfPartOfRomania()\n\t{\n\t    initMap(this);\n\t}\n\n\t// The different locations in the simplified map of part of Romania\n\tpublic const String ORADEA = \"Oradea\";\n\tpublic const String ZERIND = \"Zerind\";\n\tpublic const String ARAD = \"Arad\";\n\tpublic const String TIMISOARA = \"Timisoara\";\n\tpublic const String LUGOJ = \"Lugoj\";\n\tpublic const String MEHADIA = \"Mehadia\";\n\tpublic const String DOBRETA = \"Dobreta\";\n\tpublic const String SIBIU = \"Sibiu\";\n\tpublic const String RIMNICU_VILCEA = \"RimnicuVilcea\";\n\tpublic const String CRAIOVA = \"Craiova\";\n\tpublic const String FAGARAS = \"Fagaras\";\n\tpublic const String PITESTI = \"Pitesti\";\n\tpublic const String GIURGIU = \"Giurgiu\";\n\tpublic const String BUCHAREST = \"Bucharest\";\n\tpublic const String NEAMT = \"Neamt\";\n\tpublic const String URZICENI = \"Urziceni\";\n\tpublic const String IASI = \"Iasi\";\n\tpublic const String VASLUI = \"Vaslui\";\n\tpublic const String HIRSOVA = \"Hirsova\";\n\tpublic const String EFORIE = \"Eforie\";\n\n\t/**\n         * Initializes a map with a simplified road map of Romania.\n         */\n\tpublic static void initMap(ExtendableMap map)\n\t{\n\t    // mapOfRomania\n\t    map.clear();\n\t    map.addBidirectionalLink(ORADEA, ZERIND, 71.0);\n\t    map.addBidirectionalLink(ORADEA, SIBIU, 151.0);\n\t    map.addBidirectionalLink(ZERIND, ARAD, 75.0);\n\t    map.addBidirectionalLink(ARAD, TIMISOARA, 118.0);\n\t    map.addBidirectionalLink(ARAD, SIBIU, 140.0);\n\t    map.addBidirectionalLink(TIMISOARA, LUGOJ, 111.0);\n\t    map.addBidirectionalLink(LUGOJ, MEHADIA, 70.0);\n\t    map.addBidirectionalLink(MEHADIA, DOBRETA, 75.0);\n\t    map.addBidirectionalLink(DOBRETA, CRAIOVA, 120.0);\n\t    map.addBidirectionalLink(SIBIU, FAGARAS, 99.0);\n\t    map.addBidirectionalLink(SIBIU, RIMNICU_VILCEA, 80.0);\n\t    map.addBidirectionalLink(RIMNICU_VILCEA, PITESTI, 97.0);\n\t    map.addBidirectionalLink(RIMNICU_VILCEA, CRAIOVA, 146.0);\n\t    map.addBidirectionalLink(CRAIOVA, PITESTI, 138.0);\n\t    map.addBidirectionalLink(FAGARAS, BUCHAREST, 211.0);\n\t    map.addBidirectionalLink(PITESTI, BUCHAREST, 101.0);\n\t    map.addBidirectionalLink(GIURGIU, BUCHAREST, 90.0);\n\t    map.addBidirectionalLink(BUCHAREST, URZICENI, 85.0);\n\t    map.addBidirectionalLink(NEAMT, IASI, 87.0);\n\t    map.addBidirectionalLink(URZICENI, VASLUI, 142.0);\n\t    map.addBidirectionalLink(URZICENI, HIRSOVA, 98.0);\n\t    map.addBidirectionalLink(IASI, VASLUI, 92.0);\n\t    // addBidirectionalLink(VASLUI - already all linked\n\t    map.addBidirectionalLink(HIRSOVA, EFORIE, 86.0);\n\t    // addBidirectionalLink(EFORIE - already all linked\n\n\t    // distances and directions\n\t    // reference location: Bucharest\n\t    map.setDistAndDirToRefLocation(ARAD, 366, 117);\n\t    map.setDistAndDirToRefLocation(BUCHAREST, 0, 360);\n\t    map.setDistAndDirToRefLocation(CRAIOVA, 160, 74);\n\t    map.setDistAndDirToRefLocation(DOBRETA, 242, 82);\n\t    map.setDistAndDirToRefLocation(EFORIE, 161, 282);\n\t    map.setDistAndDirToRefLocation(FAGARAS, 176, 142);\n\t    map.setDistAndDirToRefLocation(GIURGIU, 77, 25);\n\t    map.setDistAndDirToRefLocation(HIRSOVA, 151, 260);\n\t    map.setDistAndDirToRefLocation(IASI, 226, 202);\n\t    map.setDistAndDirToRefLocation(LUGOJ, 244, 102);\n\t    map.setDistAndDirToRefLocation(MEHADIA, 241, 92);\n\t    map.setDistAndDirToRefLocation(NEAMT, 234, 181);\n\t    map.setDistAndDirToRefLocation(ORADEA, 380, 131);\n\t    map.setDistAndDirToRefLocation(PITESTI, 100, 116);\n\t    map.setDistAndDirToRefLocation(RIMNICU_VILCEA, 193, 115);\n\t    map.setDistAndDirToRefLocation(SIBIU, 253, 123);\n\t    map.setDistAndDirToRefLocation(TIMISOARA, 329, 105);\n\t    map.setDistAndDirToRefLocation(URZICENI, 80, 247);\n\t    map.setDistAndDirToRefLocation(VASLUI, 199, 222);\n\t    map.setDistAndDirToRefLocation(ZERIND, 374, 125);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/map/StraightLineDistanceHeuristicFunction.cs",
    "content": "using System;\nusing aima.core.util;\n\nnamespace aima.core.environment.map\n{\n    /**\n     * @author Ruediger Lunde\n     */\n    public class StraightLineDistanceHeuristicFunction : AdaptableHeuristicFunction\n    {\n\tpublic StraightLineDistanceHeuristicFunction(Object goal, Map map)\n\t{\n\t    this.goal = goal;\n\t    this.map = map;\n\t}\n\n\tpublic double h(Object state)\n\t{\n\t    Double result = 0.0;\n\t    Point2D pt1 = map.getPosition((String)state);\n\t    Point2D pt2 = map.getPosition((String)goal);\n\t    if (pt1 != null && pt2 != null)\n\t    {\n\t\tresult = pt1.distance(pt2);\n\t    }\n\t    return result;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/wumpusworld/AgentPercept.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.environment.wumpusworld\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 237.<br>\n     * <br>\n     * The agent has five sensors, each of which gives a single bit of information:\n     * <ul>\n     * <li>In the square containing the wumpus and in the directly (not diagonally)\n     * adjacent squares, the agent will perceive a Stench.</li>\n     * <li>In the squares directly adjacent to a pit, the agent will perceive a\n     * Breeze.</li>\n     * <li>In the square where the gold is, the agent will perceive a Glitter.</li>\n     * <li>When an agent walks into a wall, it will perceive a Bump.</li>\n     * <li>When the wumpus is killed, it emits a woeful Scream that can be perceived\n     * anywhere in the cave.</li>\n     * </ul>\n     * \n     * @author Federico Baron\n     * @author Alessandro Daniele\n     * @author Ciaran O'Reilly\n     */\n    public class AgentPercept : Percept\n    {\n\tprivate bool stench;\n\tprivate bool breeze;\n\tprivate bool glitter;\n\tprivate bool bump;\n\tprivate bool scream;\n\n\t/**\n\t * Default Constructor. All sensor inputs are considered false.\n\t */\n\tpublic AgentPercept()\n\t{\n\t    setStench(false);\n\t    setBreeze(false);\n\t    setGlitter(false);\n\t    setBump(false);\n\t    setScream(false);\n\t}\n\n\t/**\n\t * Constructor with all 5 sensor inputs explicitly set.\n\t * \n\t * @param stench\n\t * @param breeze\n\t * @param glitter\n\t * @param bump\n\t * @param scream\n\t */\n\tpublic AgentPercept(bool stench, bool breeze, bool glitter,\n\t\t\tbool bump, bool scream)\n\t{\n\t    setStench(stench);\n\t    setBreeze(breeze);\n\t    setGlitter(glitter);\n\t    setBump(bump);\n\t    setScream(scream);\n\t}\n\n\tpublic bool isStench()\n\t{\n\t    return stench;\n\t}\n\n\tpublic void setStench(bool stench)\n\t{\n\t    this.stench = stench;\n\t}\n\n\tpublic bool isBreeze()\n\t{\n\t    return breeze;\n\t}\n\n\tpublic void setBreeze(bool breeze)\n\t{\n\t    this.breeze = breeze;\n\t}\n\n\tpublic bool isGlitter()\n\t{\n\t    return glitter;\n\t}\n\n\tpublic void setGlitter(bool glitter)\n\t{\n\t    this.glitter = glitter;\n\t}\n\n\tpublic bool isBump()\n\t{\n\t    return bump;\n\t}\n\n\tpublic void setBump(bool bump)\n\t{\n\t    this.bump = bump;\n\t}\n\n\tpublic bool isScream()\n\t{\n\t    return scream;\n\t}\n\n\tpublic void setScream(bool scream)\n\t{\n\t    this.scream = scream;\n\t}\n\n\tpublic string toString()\n\t{\n\t    return \"[\" + ((stench) ? \"Stench\" : \"None\") + \", \"\n\t\t\t      + ((breeze) ? \"Breeze\" : \"None\") + \", \"\n\t\t\t      + ((glitter) ? \"Glitter\" : \"None\") + \", \"\n\t\t\t      + ((bump) ? \"Bump\" : \"None\") + \", \"\n\t\t\t      + ((scream) ? \"Scream\" : \"None\") + \"]\";\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/environment/wumpusworld/AgentPosition.cs",
    "content": "﻿using System;\n\nnamespace aima.core.environment.wumpusworld\n{\n    internal class AgentPosition\n    {\n        internal int getX()\n        {\n            throw new NotImplementedException();\n        }\n\n        internal int getY()\n        {\n            throw new NotImplementedException();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/wumpusworld/ManhattanHeuristicFunction.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.search.framework;\n\nnamespace aima.core.environment.wumpusworld\n{\n    /**\n     * Heuristic for calculating the Manhattan distance between two rooms within a Wumpus World cave.\n     * \n     * @author Federico Baron\n     * @author Alessandro Daniele\n     * @author Ciaran O'Reilly\n     */\n    public class ManhattanHeuristicFunction : HeuristicFunction\n    {\n\tList<Room> goals = new List<Room>();\n\n\tpublic ManhattanHeuristicFunction(HashSet<Room> goals)\n\t{\n\t    this.goals.AddRange(goals);\n\t}\n\n\tpublic double h(Object state)\n\t{\n\t    AgentPosition pos = (AgentPosition)state;\n\t    int nearestGoalDist = int.MaxValue;\n\t    foreach (Room g in goals)\n\t    {\n\t\tint tmp = evaluateManhattanDistanceOf(pos.getX(), pos.getY(), g.getX(), g.getY());\n\n\t\tif (tmp < nearestGoalDist)\n\t\t{\n\t\t    nearestGoalDist = tmp;\n\t\t}\n\t    }\n\t    return nearestGoalDist;\n\t}\n\n\t// PRIVATE\n\n\tprivate int evaluateManhattanDistanceOf(int x1, int y1, int x2, int y2)\n\t{\n\t    return Math.Abs(x1 - x2) + Math.Abs(y1 - y2);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/environment/wumpusworld/Room.cs",
    "content": "using System.Collections.Generic;\n\nnamespace aima.core.environment.wumpusworld\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 236.<br>\n     * <br>\n     * The <b>wumpus world</b> is a cave consisting of rooms connected by\n     * passageways. Rooms are labeled [x,y], for example [1,1] would indicate the\n     * room in the bottom left, and is also the room the agent always starts in. See\n     * Figure 7.2 for an example room layout representing a wumpus's cave.\n     * \n     * @author Ciaran O'Reilly\n     */\n    public class Room\n    {\n\tprivate int x = 1;\n\tprivate int y = 1;\n\n\t/**\n\t * Constructor.\n\t * \n\t * @param x\n\t *            the room's x location.\n\t * @param y\n\t *            the room's y location.\n\t */\n\tpublic Room(int x, int y)\n\t{\n\t    this.x = x;\n\t    this.y = y;\n\t}\n\n\t/**\n\t * \n\t * @return the room's x location.\n\t */\n\tpublic int getX()\n\t{\n\t    return x;\n\t}\n\n\t/**\n\t *\n\t * @return the room's y location.\n\t */\n\tpublic int getY()\n\t{\n\t    return y;\n\t}\n\n\tpublic string toString()\n\t{\n\t    return \"[\" + x + \",\" + y + \"]\";\t    \n\t}\n\t\n\tpublic bool equals(object o)\n\t{\n\t    if (o != null && o is Room) {\n\t\tRoom r = (Room)o;\n\t\tif (x == r.x && y == r.y)\n\t\t{\n\t\t    return true;\n\t\t}\n\t\treturn false;\n\t    }\n\t    return false;\n\t}\n\n\tpublic int hashCode()\n\t{\n\t    int result = 17;\n\t    result = 37 * result + getX();\n\t    result = 43 * result + getY();\n\t    return result;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/common/Lexer.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\n\nnamespace aima.core.logic.common\n{\n    /**\n     * An abstract base class for constructing lexical analyzers for knowledge\n     * representation languages. It provides a mechanism for converting a sequence\n     * of characters to a sequence of tokens that are meaningful in the\n     * representation language of interest.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n    public abstract class Lexer\n    {\n\tprotected int lookAheadBufferSize = 1;\n\t//\n\tprivate static readonly int END_OF_INPUT = -1;\n\t//\n\tprivate StringReader input;\n\tpublic int[] lookAheadBuffer;\n\tprivate int currentPositionInInput;\n\n\t/**\n\t * Sets the character stream of the lexical analyzer.\n\t * \n\t * @param inputString\n\t *            a sequence of characters to be converted into a sequence of\n\t *            tokens.\n\t */\n\tpublic void setInput(String inputString)\n\t{\n\t    this.input = new StringReader(inputString);\n\t}\n\n\t/**\n\t * Set the character stream reader of the lexical analyzer.\n\t * \n\t * @param inputReader\n\t *            a reader on a sequence of characters to be converted into a\n\t *            sequence of tokens.\n\t */\n\tpublic void setInput(StringReader inputReader)\n\t{\n\t    input = inputReader;\n\t    lookAheadBuffer = new int[lookAheadBufferSize];\n\t    currentPositionInInput = 0;\n\t    initializeLookAheadBuffer();\n\t}\n\n\t/**\n\t * To be implemented by concrete implementations\n\t * \n\t * @return the next token from the input.\n\t */\n\tpublic abstract Token nextToken();\n\n\t// PROTECTED\n\t\n\tprotected int getCurrentPositionInInput()\n\t{\n\t    return currentPositionInInput;\n\t}\n\n\t/*\n\t * Returns the character at the specified position in the lookahead buffer.\n\t */\n\tprotected char lookAhead(int position)\n\t{\n\t    return (char)lookAheadBuffer[position - 1];\n\t}\n\n\t/**\n\t * Consume 1 character from the input.\n\t */\n\tprotected void consume()\n\t{\n\t    currentPositionInInput++;\n\t    loadNextCharacterFromInput();\n\t}\n\n\t// PRIVATE\n\t\n\t/**\n\t * Returns true if the end of the stream has been reached.\n\t */\n\tprivate bool isEndOfInput(int i)\n\t{\n\t    return (END_OF_INPUT == i);\n\t}\n\n\t/**\n\t * Initialize the look ahead buffer from the input.\n\t */\n\tprivate void initializeLookAheadBuffer()\n\t{\n\t    for (int i = 0; i < lookAheadBufferSize; i++)\n\t    {\n\t\t// Mark th entire buffer as being end of input.\n\t\tlookAheadBuffer[i] = END_OF_INPUT;\n\t    }\n\t    for (int i = 0; i < lookAheadBufferSize; i++)\n\t    {\n\t\t// Now fill the buffer (if possible) from the input.\n\t\tlookAheadBuffer[i] = readInput();\n\t\tif (isEndOfInput(lookAheadBuffer[i]))\n\t\t{\n\t\t    // The input is smaller than the buffer size\n\t\t    break;\n\t\t}\n\t    }\n\t}\n\n\t/**\n\t * Loads the next character into the lookahead buffer if the end of the\n\t * stream has not already been reached.\n\t */\n\tprivate void loadNextCharacterFromInput()\n\t{\n\t    bool eoiEncountered = false;\n\t    for (int i = 0; i < lookAheadBufferSize - 1; i++)\n\t    {\n\t\tlookAheadBuffer[i] = lookAheadBuffer[i + 1];\n\t\tif (isEndOfInput(lookAheadBuffer[i]))\n\t\t{\n\t\t    eoiEncountered = true;\n\t\t    break;\n\t\t}\n\t    }\n\t    if (!eoiEncountered)\n\t    {\n\t\tlookAheadBuffer[lookAheadBufferSize - 1] = readInput();\n\t    }\n\t}\n\n\tprivate int readInput()\n\t{\n\t    int read = -1;\n\n\t    try\n\t    {\n\t\tread = input.Read();\n\t    }\n\t    catch (IOException ioe)\n\t    {\n\t\tthrow new LexerException(\"IOException thrown reading input.\",\n\t\t\t\tcurrentPositionInInput, ioe);\n\t    }\n\t    return read;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/common/LexerException.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.logic.common\n{\n    /**\n     * A runtime exception to be used to describe Lexer exceptions. In particular it\n     * provides information to help in identifying where in the input character\n     * sequence the exception occurred.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class LexerException : SystemException\n    {\n\tprivate static readonly long serialVersionUID = 1L;\n\n\tprivate int currentPositionInInput;\n\n\tpublic LexerException(String message, int currentPositionInInput): base(message)\n\t{\t    \n\t    this.currentPositionInInput = currentPositionInInput;\n\t}\n\n\tpublic LexerException(String message, int currentPositionInInput,\n\t\t\tException cause): base(message, cause)\n\t{\n\t    \n\t    this.currentPositionInInput = currentPositionInInput;\n\t}\n\n\t/**\n\t * \n\t * @return the current position in the input character stream that the lexer\n\t *         was at before the exception was encountered.\n\t */\n\tpublic int getCurrentPositionInInputExceptionThrown()\n\t{\n\t    return currentPositionInInput;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/common/LogicTokenTypes.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.logic.common\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public enum LogicTokenTypes : int\n    {\n\tSYMBOL = 1,\n\n\tLPAREN = 2,\n\n\tRPAREN = 3,\n\n\tCOMMA = 4,\n\n\tCONNECTOR = 5,\n\n\tQUANTIFIER = 6,\n\n\tPREDICATE = 7,\n\n\tFUNCTION = 8,\n\n\tVARIABLE = 9,\n\n\tCONSTANT = 10,\n\n\tTRUE = 11,\n\n\tFALSE = 12,\n\n\tEQUALS = 13,\n\n\tWHITESPACE = 1000,\n\n\tEOI = 9999 // End of Input.\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/common/Parser.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.IO;\n\nnamespace aima.core.logic.common\n{\n\n    /**\n     * An abstract base class for constructing parsers for knowledge representation\n     * languages. It provides a mechanism for converting a sequence of tokens\n     * (derived from an appropriate lexer) into a syntactically correct abstract\n     * syntax tree of the representation language.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * \n     * @param <S> the root type of the abstract syntax tree being parsed.\n     */\n    public abstract class Parser<S>\n    {\n\tprotected int lookAheadBufferSize = 1;\n\t\n\tprivate Token[] lookAheadBuffer = null;\n\tprivate StringReader input;\n\n\t/**\n\t * \n\t * @return an instance of the Lexer to be used by a concrete implementation\n\t *         of this class.\n\t */\n\tpublic abstract Lexer getLexer();\n\n\t/**\n\t * Parse the input concrete syntax into an abstract syntax tree.\n\t * \n\t * @param input\n\t *            a string representation of the concrete syntax to be parsed.\n\t * @return the root node of an abstract syntax tree representation of the\n\t *         the concrete input syntax that was parsed.\n\t */\n\tpublic S parse(String input)\n\t{\n\t    return parse(new StringReader(input));\n\t}\n\n\t/**\n\t * Parse the input concrete syntax into an abstract syntax tree.\n\t * \n\t * @param inputReader\n\t *            a Reader of the concrete syntax to be parsed.\n\t * @return the root node of an abstract syntax tree representation of the\n\t *         the concrete input syntax that was parsed.\n\t */\n\tpublic S parse(StringReader inputReader)\n\t{\n\t    S result;\n\n\t    try\n\t    {\n\t\tgetLexer().setInput(inputReader);\n\t\tinitializeLookAheadBuffer();\n\n\t\tresult = parse();\n\t    }\n\t    catch (LexerException le)\n\t    {\n\t\tthrow new ParserException(\"Lexer Exception thrown during parsing at position \" + le.getCurrentPositionInInputExceptionThrown(), le);\n\t    }\n\t    return default(S);\n\t}\n\n\t// PROTECTED\n\t\n\t/**\n\t * To be implemented by concrete implementations of this class.\n\t * \n\t * @return the root node of an abstract syntax tree representation of the\n\t *         the concrete input syntax that was parsed.\n\t */\n\tprotected abstract S parse();\n\n\t/**\n\t * @return the token at the specified position in the lookahead buffer.\n\t */\n\tprotected Token lookAhead(int i)\n\t{\n\t    return lookAheadBuffer[i - 1];\n\t}\n\n\t/**\n\t * Consume 1 token from the input.\n\t */\n\tprotected void consume()\n\t{\n\t    loadNextTokenFromInput();\n\t}\n\n\t/**\n\t * Consume the given match symbol if it matches the current input token. If\n\t * it does not match throws a ParserException detailing the match error.\n\t * \n\t * @param toMatchSymbol\n\t *            the symbol to match before consuming it.\n\t */\n\tprotected void match(String toMatchSymbol)\n\t{\n\t    if (lookAhead(1).getText().Equals(toMatchSymbol))\n\t    {\n\t\tconsume();\n\t    }\n\t    else\n\t    {\n\t\tthrow new ParserException(\n\t\t\t\t\"Parser: Syntax error detected at match. Expected \"\n\t\t\t\t\t\t+ toMatchSymbol + \" but got \"\n\t\t\t\t\t\t+ lookAhead(1).getText(), lookAhead(1));\n\t    }\n\n\t}\n\t\t\n\t// PRIVATE\n\t\n\tprivate void initializeLookAheadBuffer()\n\t{\n\t    lookAheadBuffer = new Token[lookAheadBufferSize];\n\t    for (int i = 0; i < lookAheadBufferSize; i++)\n\t    {\n\t\t// Now fill the buffer (if possible) from the input.\n\t\tlookAheadBuffer[i] = getLexer().nextToken();\n\t\tif (isEndOfInput(lookAheadBuffer[i]))\n\t\t{\n\t\t    // The input is smaller than the buffer size\n\t\t    break;\n\t\t}\n\t    }\n\t}\n\n\t/*\n\t * Loads the next token into the lookahead buffer if the end of the stream\n\t * has not already been reached.\n\t */\n\tprivate void loadNextTokenFromInput()\n\t{\n\t    bool eoiEncountered = false;\n\t    for (int i = 0; i < lookAheadBufferSize - 1; i++)\n\t    {\n\t\tlookAheadBuffer[i] = lookAheadBuffer[i + 1];\n\t\tif (isEndOfInput(lookAheadBuffer[i]))\n\t\t{\n\t\t    eoiEncountered = true;\n\t\t    break;\n\t\t}\n\t    }\n\t    if (!eoiEncountered)\n\t    {\n\t\tlookAheadBuffer[lookAheadBufferSize - 1] = getLexer().nextToken();\n\t    }\n\t}\n\n\t/*\n\t * Returns true if the end of the stream has been reached.\n\t */\n\tprivate bool isEndOfInput(Token t)\n\t{\n\t    return (t == null || EqualityComparer<Token>.Equals(t.getType(), LogicTokenTypes.EOI));\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/common/ParserException.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.logic.common\n{\n    /**\n     * A runtime exception to be used to describe Parser exceptions. In particular\n     * it provides information to help in identifying which tokens proved\n     * problematic in the parse.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ParserException : SystemException\n    {\n\tprivate static readonly long serialVersionUID = 1L;\n\n\tprivate List<Token> problematicTokens = new List<Token>();\n\n\tpublic ParserException(String message, params Token[] problematicTokens): base(message)\n\t{\t    \n\t    if (problematicTokens != null)\n\t    {\n\t\tforeach (Token pt in problematicTokens)\n\t\t{\n\t\t    this.problematicTokens.Add(pt);\n\t\t}\n\t    }\n\t}\n\n\tpublic ParserException(String message, Exception cause, params Token[] problematicTokens): base(message, cause)\n\t{\t    \n\t    if (problematicTokens != null)\n\t    {\n\t\tforeach (Token pt in problematicTokens)\n\t\t{\n\t\t    this.problematicTokens.Add(pt);\n\t\t}\n\t    }\n\t}\n\n\t/**\n\t * \n\t * @return a list of 0 or more tokens from the input stream that are\n\t *         believed to have contributed to the parse exception.\n\t */\n\tpublic List<Token> getProblematicTokens()\n\t{\n\t    return problematicTokens;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/common/ParserTreeNode.cs",
    "content": "namespace aima.core.logic.common\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public interface ParseTreeNode\n    {\n\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/common/Token.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.logic.common\n{\n    /**\n     * A token generated by a lexer from a sequence of characters.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n    public class Token\n    {\n\tprivate int type;\n\tprivate String text;\n\tprivate int startCharPositionInInput;\n\n\t/**\n\t * Constructs a token from the specified token-name and attribute-value\n\t * \n\t * @param type\n\t *            the token-name\n\t * @param text\n\t *            the attribute-value\n\t * @param startCharPositionInInput\n\t *            the position (starting from 0) at which this token \n\t *            starts in  the input.\n\t */\n\tpublic Token(int type, String text, int startCharPositionInInput)\n\t{\n\t    this.type = type;\n\t    this.text = text;\n\t    this.startCharPositionInInput = startCharPositionInInput;\n\t}\n\n\t/**\n\t * Returns the attribute-value of this token.\n\t * \n\t * @return the attribute-value of this token.\n\t */\n\tpublic String getText()\n\t{\n\t    return text;\n\t}\n\n\t/**\n\t * Returns the token-name of this token.\n\t * \n\t * @return the token-name of this token.\n\t */\n\tpublic int getType()\n\t{\n\t    return type;\n\t}\n\n\t/**\n\t * @return the position (starting from 0) at which this token starts in the\n\t *         input.\n\t */\n\tpublic int getStartCharPositionInInput()\n\t{\n\t    return startCharPositionInInput;\n\t}\n\n\tpublic  override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if ((o == null) || !(o is Token))\n\t    {\n\t\treturn false;\n\t    }\n\n\t    Token other = (Token)o;\n\t    return ((other.type == type) && (other.text.Equals(text)) && (other.startCharPositionInInput == startCharPositionInInput));\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    int result = 17;\n\t    result = 37 * result + type;\n\t    result = 37 * result + text.GetHashCode();\n\t    result = 37 * result + startCharPositionInInput;\n\t    return result;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    return \"[ \" + type + \" \" + text + \" \" + startCharPositionInInput + \" ]\";\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/CNFConverter.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.parsing.ast;\nusing aima.core.util;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 345.<br>\n     * <br>\n     * Every sentence of first-order logic can be converted into an inferentially\n     * equivalent CNF sentence.<br>\n     * <br>\n     * <b>Note:</b> Transformation rules extracted from 346 and 347, which are\n     * essentially the INSEADO method outlined in: <a\n     * href=\"http://logic.stanford.edu/classes/cs157/2008/lectures/lecture09.pdf\"\n     * >INSEADO Rules</a>\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n     public class CNFConverter\n    {\n\tprivate FOLParser parser = null;\n\tprivate SubstVisitor substVisitor;\n\n\tpublic CNFConverter(FOLParser parser)\n\t{\n\t    this.parser = parser;\n\n\t    this.substVisitor = new SubstVisitor();\n\t}\n\n\t/**\n\t * Returns the specified sentence as a list of clauses, where each clause is\n\t * a disjunction of literals.\n\t * \n\t * @param aSentence\n\t *            a sentence in first order logic (predicate calculus)\n\t * \n\t * @return the specified sentence as a list of clauses, where each clause is\n\t *         a disjunction of literals.\n\t */\n\tpublic CNF convertToCNF(Sentence aSentence)\n\t{\n\t    // I)mplications Out:\n\t    Sentence implicationsOut = (Sentence)aSentence.accept(\n\t\t\t    new ImplicationsOut(), null);\n\n\t    // N)egations In:\n\t    Sentence negationsIn = (Sentence)implicationsOut.accept(\n\t\t\t    new NegationsIn(), null);\n\n\t    // S)tandardize variables:\n\t    // For sentences like:\n\t    // (FORALL x P(x)) V (EXISTS x Q(x)),\n\t    // which use the same variable name twice, change the name of one of the\n\t    // variables.\n\t    Sentence saQuantifiers = (Sentence)negationsIn.accept(\n\t\t\t    new StandardizeQuantiferVariables(substVisitor),\n\t\t\t    new LinkedHashSet<Variable>());\n\n\t    // Remove explicit quantifiers, by skolemizing existentials\n\t    // and dropping universals:\n\t    // E)xistentials Out\n\t    // A)lls Out:\n\t    Sentence andsAndOrs = (Sentence)saQuantifiers.accept(\n\t\t\t    new RemoveQuantifiers(parser), new LinkedHashSet<Variable>());\n\n\t    // D)istribution\n\t    // V over ^:\n\t    Sentence orDistributedOverAnd = (Sentence)andsAndOrs.accept(\n\t\t\t    new DistributeOrOverAnd(), null);\n\n\t    // O)perators Out\n\t    return (new CNFConstructor()).construct(orDistributedOverAnd);\n\t}\n    }\n\n    class ImplicationsOut : FOLVisitor\n    {\n\tpublic ImplicationsOut()\n\t{\n\n\t}\n\n\tpublic Object visitPredicate(Predicate p, Object arg)\n\t{\n\t    return p;\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    return equality;\n\t}\n\n\tpublic Object visitVariable(Variable variable, Object arg)\n\t{\n\t    return variable;\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    return constant;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    return function;\n\t}\n\n\tpublic Object visitNotSentence(NotSentence notSentence, Object arg)\n\t{\n\t    Sentence negated = notSentence.getNegated();\n\n\t    return new NotSentence((Sentence)negated.accept(this, arg));\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    Sentence alpha = (Sentence)sentence.getFirst().accept(this, arg);\n\t    Sentence beta = (Sentence)sentence.getSecond().accept(this, arg);\n\n\t    // Eliminate <=>, bi-conditional elimination,\n\t    // replace (alpha <=> beta) with (~alpha V beta) ^ (alpha V ~beta).\n\t    if (Connectors.isBICOND(sentence.getConnector()))\n\t    {\n\t\tSentence first = new ConnectedSentence(Connectors.OR,\n\t\t\tnew NotSentence(alpha), beta);\n\t\tSentence second = new ConnectedSentence(Connectors.OR, alpha,\n\t\t\tnew NotSentence(beta));\n\n\t\treturn new ConnectedSentence(Connectors.AND, first, second);\n\t    }\n\n\t    // Eliminate =>, implication elimination,\n\t    // replacing (alpha => beta) with (~alpha V beta)\n\t    if (Connectors.isIMPLIES(sentence.getConnector()))\n\t    {\n\t\treturn new ConnectedSentence(Connectors.OR, new NotSentence(alpha),\n\t\t\tbeta);\n\t    }\n\n\t    return new ConnectedSentence(sentence.getConnector(), alpha, beta);\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\n\t    return new QuantifiedSentence(sentence.getQuantifier(), sentence\n\t\t    .getVariables(), (Sentence)sentence.getQuantified().accept(\n\t\t    this, arg));\n\t}\n    }\n\n    class NegationsIn : FOLVisitor\n    {\n\tpublic NegationsIn()\n\t{\n\n\t}\n\n\tpublic Object visitPredicate(Predicate p, Object arg)\n\t{\n\t    return p;\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    return equality;\n\t}\n\n\tpublic Object visitVariable(Variable variable, Object arg)\n\t{\n\t    return variable;\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    return constant;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    return function;\n\t}\n\n\tpublic Object visitNotSentence(NotSentence notSentence, Object arg)\n\t{\n\t    // CNF requires NOT (~) to appear only in literals, so we 'move ~\n\t    // inwards' by repeated application of the following equivalences:\n\t    Sentence negated = notSentence.getNegated();\n\n\t    // ~(~alpha) equivalent to alpha (double negation elimination)\n\t    if (negated is NotSentence)\n\t    {\n\t\treturn ((NotSentence)negated).getNegated().accept(this, arg);\n\t    }\n\n\t    if (negated is ConnectedSentence)\n\t    {\n\t\tConnectedSentence negConnected = (ConnectedSentence)negated;\n\t\tSentence alpha = negConnected.getFirst();\n\t\tSentence beta = negConnected.getSecond();\n\t\t// ~(alpha ^ beta) equivalent to (~alpha V ~beta) (De Morgan)\n\t\tif (Connectors.isAND(negConnected.getConnector()))\n\t\t{\n\t\t    // I need to ensure the ~s are moved in deeper\n\t\t    Sentence notAlpha = (Sentence)(new NotSentence(alpha)).accept(\n\t\t\t    this, arg);\n\t\t    Sentence notBeta = (Sentence)(new NotSentence(beta)).accept(\n\t\t\t    this, arg);\n\t\t    return new ConnectedSentence(Connectors.OR, notAlpha, notBeta);\n\t\t}\n\n\t\t// ~(alpha V beta) equivalent to (~alpha ^ ~beta) (De Morgan)\n\t\tif (Connectors.isOR(negConnected.getConnector()))\n\t\t{\n\t\t    // I need to ensure the ~s are moved in deeper\n\t\t    Sentence notAlpha = (Sentence)(new NotSentence(alpha)).accept(\n\t\t\t    this, arg);\n\t\t    Sentence notBeta = (Sentence)(new NotSentence(beta)).accept(\n\t\t\t    this, arg);\n\t\t    return new ConnectedSentence(Connectors.AND, notAlpha, notBeta);\n\t\t}\n\t    }\n\n\t    // in addition, rules for negated quantifiers:\n\t    if (negated is QuantifiedSentence)\n\t    {\n\t\tQuantifiedSentence negQuantified = (QuantifiedSentence)negated;\n\t\t// I need to ensure the ~ is moved in deeper\n\t\tSentence notP = (Sentence)(new NotSentence(negQuantified\n\t\t\t.getQuantified())).accept(this, arg);\n\n\t\t// ~FORALL x p becomes EXISTS x ~p\n\t\tif (Quantifiers.isFORALL(negQuantified.getQuantifier()))\n\t\t{\n\t\t    return new QuantifiedSentence(Quantifiers.EXISTS, negQuantified\n\t\t\t    .getVariables(), notP);\n\t\t}\n\n\t\t// ~EXISTS x p becomes FORALL x ~p\n\t\tif (Quantifiers.isEXISTS(negQuantified.getQuantifier()))\n\t\t{\n\t\t    return new QuantifiedSentence(Quantifiers.FORALL, negQuantified\n\t\t\t    .getVariables(), notP);\n\t\t}\n\t    }\n\n\t    return new NotSentence((Sentence)negated.accept(this, arg));\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    return new ConnectedSentence(sentence.getConnector(),\n\t\t    (Sentence)sentence.getFirst().accept(this, arg),\n\t\t    (Sentence)sentence.getSecond().accept(this, arg));\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\n\t    return new QuantifiedSentence(sentence.getQuantifier(), sentence\n\t\t    .getVariables(), (Sentence)sentence.getQuantified().accept(\n\t\t    this, arg));\n\t}\n    }\n\n    class StandardizeQuantiferVariables : FOLVisitor\n    {\n\t// Just use a localized indexical here.\n\tprivate ApartIndexical quantifiedIndexical = new ApartIndexical();\n\n\tprivate class ApartIndexical : StandardizeApartIndexical\n\t{\n\t    private int index = 0;\n\n\t    public String getPrefix()\n\t    {\n\t\treturn \"q\";\n\t    }\n\n\t    public int getNextIndex()\n\t    {\n\t\treturn index++;\n\t    }\n\t}\n\n\tprivate SubstVisitor substVisitor = null;\n\n\tpublic StandardizeQuantiferVariables(SubstVisitor substVisitor)\n\t{\n\t    this.substVisitor = substVisitor;\n\t}\n\n\tpublic Object visitPredicate(Predicate p, Object arg)\n\t{\n\t    return p;\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    return equality;\n\t}\n\n\tpublic Object visitVariable(Variable variable, Object arg)\n\t{\n\t    return variable;\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    return constant;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    return function;\n\t}\n\n\tpublic Object visitNotSentence(NotSentence sentence, Object arg)\n\t{\n\t    return new NotSentence((Sentence)sentence.getNegated().accept(this,\n\t\t    arg));\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    return new ConnectedSentence(sentence.getConnector(),\n\t\t    (Sentence)sentence.getFirst().accept(this, arg),\n\t\t    (Sentence)sentence.getSecond().accept(this, arg));\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\t    List<Variable> seenSoFar = (List<Variable>)arg;\n\n\t    // Keep track of what I have to subst locally and\n\t    // what my renamed variables will be.\n\t    Dictionary<Variable, Term> localSubst = new Dictionary<Variable, Term>();\n\t    List<Variable> replVariables = new List<Variable>();\n\t    foreach (Variable v in sentence.getVariables())\n\t    {\n\t\t// If local variable has be renamed already\n\t\t// then I need to come up with own name\n\t\tif (seenSoFar.Contains(v))\n\t\t{\n\t\t    Variable sV = new Variable(quantifiedIndexical.getPrefix()\n\t\t\t    + quantifiedIndexical.getNextIndex());\n\t\t    localSubst.Add(v, sV);\n\t\t    // Replacement variables should contain new name for variable\n\t\t    replVariables.Add(sV);\n\t\t}\n\t\telse\n\t\t{\n\t\t    // Not already replaced, this name is good\n\t\t    replVariables.Add(v);\n\t\t}\n\t    }\n\n\t    // Apply the local subst\n\t    Sentence subst = substVisitor.subst(localSubst, sentence\n\t\t    .getQuantified());\n\n\t    // Ensure all my existing and replaced variable\n\t    // names are tracked\n\t    seenSoFar.AddRange(replVariables);\n\n\t    Sentence sQuantified = (Sentence)subst.accept(this, arg);\n\n\t    return new QuantifiedSentence(sentence.getQuantifier(), replVariables,\n\t\t    sQuantified);\n\t}\n    }\n\n    class RemoveQuantifiers : FOLVisitor\n    {\n\n\tprivate FOLParser parser = null;\n\tprivate SubstVisitor substVisitor = null;\n\n\tpublic RemoveQuantifiers(FOLParser parser)\n\t{\n\t    this.parser = parser;\n\n\t    substVisitor = new SubstVisitor();\n\t}\n\n\tpublic Object visitPredicate(Predicate p, Object arg)\n\t{\n\t    return p;\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    return equality;\n\t}\n\n\tpublic Object visitVariable(Variable variable, Object arg)\n\t{\n\t    return variable;\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    return constant;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    return function;\n\t}\n\n\tpublic Object visitNotSentence(NotSentence sentence, Object arg)\n\t{\n\t    return new NotSentence((Sentence)sentence.getNegated().accept(this,\n\t\t    arg));\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    return new ConnectedSentence(sentence.getConnector(),\n\t\t    (Sentence)sentence.getFirst().accept(this, arg),\n\t\t    (Sentence)sentence.getSecond().accept(this, arg));\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\t    Sentence quantified = sentence.getQuantified();\n\t    List<Variable> universalScope = (List<Variable>)arg;\n\n\t    // Skolemize: Skolemization is the process of removing existential\n\t    // quantifiers by elimination. This is done by introducing Skolem\n\t    // functions. The general rule is that the arguments of the Skolem\n\t    // function are all the universally quantified variables in whose\n\t    // scope the existential quantifier appears.\n\t    if (Quantifiers.isEXISTS(sentence.getQuantifier()))\n\t    {\n\t\tDictionary<Variable, Term> skolemSubst = new Dictionary<Variable, Term>();\n\t\tforeach (Variable eVar in sentence.getVariables())\n\t\t{\n\t\t    if (universalScope.Count > 0)\n\t\t    {\n\t\t\t// Replace with a Skolem Function\n\t\t\tString skolemFunctionName = parser.getFOLDomain()\n\t\t\t\t.addSkolemFunction();\n\t\t\tskolemSubst.Add(eVar, new Function(skolemFunctionName,\n\t\t\t\tnew List<Term>(universalScope)));\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\t// Replace with a Skolem Constant\n\t\t\tString skolemConstantName = parser.getFOLDomain()\n\t\t\t\t.addSkolemConstant();\n\t\t\tskolemSubst.Add(eVar, new Constant(skolemConstantName));\n\t\t    }\n\t\t}\n\n\t\tSentence skolemized = substVisitor.subst(skolemSubst, quantified);\n\t\treturn skolemized.accept(this, arg);\n\t    }\n\n\t    // Drop universal quantifiers.\n\t    if (Quantifiers.isFORALL(sentence.getQuantifier()))\n\t    {\n\t\t// Add to the universal scope so that\n\t\t// existential skolemization may be done correctly\n\t\tuniversalScope.AddRange(sentence.getVariables());\n\n\t\tSentence droppedUniversal = (Sentence)quantified.accept(this, arg);\n\n\t\t// Enusre my scope is removed before moving back up\n\t\t// the call stack when returning\n\t\tforeach (Variable s in sentence.getVariables())\n\t\t{\n\t\t    universalScope.Remove(s);\n\t\t}\n\n\t\treturn droppedUniversal;\n\t    }\n\n\t    // Should not reach here as have already\n\t    // handled the two quantifiers.\n\t    throw new ApplicationException(\"Unhandled Quantifier:\"\n\t\t    + sentence.getQuantifier());\n\t}\n    }\n\n    class DistributeOrOverAnd : FOLVisitor\n    {\n\n\tpublic DistributeOrOverAnd()\n\t{\n\n\t}\n\n\tpublic Object visitPredicate(Predicate p, Object arg)\n\t{\n\t    return p;\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    return equality;\n\t}\n\n\tpublic Object visitVariable(Variable variable, Object arg)\n\t{\n\t    return variable;\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    return constant;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    return function;\n\t}\n\n\tpublic Object visitNotSentence(NotSentence sentence, Object arg)\n\t{\n\t    return new NotSentence((Sentence)sentence.getNegated().accept(this,\n\t\t    arg));\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    // Distribute V over ^:\n\n\t    // This will cause flattening out of nested ^s and Vs\n\t    Sentence alpha = (Sentence)sentence.getFirst().accept(this, arg);\n\t    Sentence beta = (Sentence)sentence.getSecond().accept(this, arg);\n\n\t    // (alpha V (beta ^ gamma)) equivalent to\n\t    // ((alpha V beta) ^ (alpha V gamma))\n\t    if (Connectors.isOR(sentence.getConnector())\n\t\t    && beta is ConnectedSentence)\n\t    {\n\t\tConnectedSentence betaAndGamma = (ConnectedSentence)beta;\n\t\tif (Connectors.isAND(betaAndGamma.getConnector()))\n\t\t{\n\t\t    beta = betaAndGamma.getFirst();\n\t\t    Sentence gamma = betaAndGamma.getSecond();\n\t\t    return new ConnectedSentence(Connectors.AND,\n\t\t\t    (Sentence)(new ConnectedSentence(Connectors.OR, alpha,\n\t\t\t\t    beta)).accept(this, arg),\n\t\t\t    (Sentence)(new ConnectedSentence(Connectors.OR, alpha,\n\t\t\t\t    gamma)).accept(this, arg));\n\t\t}\n\t    }\n\n\t    // ((alpha ^ gamma) V beta) equivalent to\n\t    // ((alpha V beta) ^ (gamma V beta))\n\t    if (Connectors.isOR(sentence.getConnector())\n\t\t    && alpha is ConnectedSentence)\n\t    {\n\t\tConnectedSentence alphaAndGamma = (ConnectedSentence)alpha;\n\t\tif (Connectors.isAND(alphaAndGamma.getConnector()))\n\t\t{\n\t\t    alpha = alphaAndGamma.getFirst();\n\t\t    Sentence gamma = alphaAndGamma.getSecond();\n\t\t    return new ConnectedSentence(Connectors.AND,\n\t\t\t    (Sentence)(new ConnectedSentence(Connectors.OR, alpha,\n\t\t\t\t    beta)).accept(this, arg),\n\t\t\t    (Sentence)(new ConnectedSentence(Connectors.OR, gamma,\n\t\t\t\t    beta)).accept(this, arg));\n\t\t}\n\t    }\n\n\t    return new ConnectedSentence(sentence.getConnector(), alpha, beta);\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\t    // This should not be called as should have already\n\t    // removed all of the quantifiers.\n\t    throw new NotImplementedException(\n\t\t    \"All quantified sentences should have already been removed.\");\n\t}\n    }\n\n    class CNFConstructor : FOLVisitor\n    {\n\tpublic CNFConstructor()\n\t{\n\n\t}\n\n\tpublic CNF construct(Sentence orDistributedOverAnd)\n\t{\n\t    ArgData ad = new ArgData();\n\n\t    orDistributedOverAnd.accept(this, ad);\n\n\t    return new CNF(ad.clauses);\n\t}\n\n\tpublic Object visitPredicate(Predicate p, Object arg)\n\t{\n\t    ArgData ad = (ArgData)arg;\n\t    if (ad.negated)\n\t    {\n\t\tad.clauses[ad.clauses.Count - 1].addNegativeLiteral(p);\n\t    }\n\t    else\n\t    {\n\t\tad.clauses[ad.clauses.Count - 1].addPositiveLiteral(p);\n\t    }\n\t    return p;\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    ArgData ad = (ArgData)arg;\n\t    if (ad.negated)\n\t    {\n\t\tad.clauses[ad.clauses.Count - 1].addNegativeLiteral(equality);\n\t    }\n\t    else\n\t    {\n\t\tad.clauses[ad.clauses.Count - 1].addPositiveLiteral(equality);\n\t    }\n\t    return equality;\n\t}\n\n\tpublic Object visitVariable(Variable variable, Object arg)\n\t{\n\t    // This should not be called\n\t    throw new NotImplementedException(\"visitVariable() should not be called.\");\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    // This should not be called\n\t    throw new NotImplementedException(\"visitConstant() should not be called.\");\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    // This should not be called\n\t    throw new NotImplementedException(\"visitFunction() should not be called.\");\n\t}\n\n\tpublic Object visitNotSentence(NotSentence sentence, Object arg)\n\t{\n\t    ArgData ad = (ArgData)arg;\n\t    // Indicate that the enclosed predicate is negated\n\t    ad.negated = true;\n\t    sentence.getNegated().accept(this, arg);\n\t    ad.negated = false;\n\n\t    return sentence;\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    ArgData ad = (ArgData)arg;\n\t    Sentence first = sentence.getFirst();\n\t    Sentence second = sentence.getSecond();\n\n\t    first.accept(this, arg);\n\t    if (Connectors.isAND(sentence.getConnector()))\n\t    {\n\t\tad.clauses.Add(new Clause());\n\t    }\n\t    second.accept(this, arg);\n\n\t    return sentence;\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\t    // This should not be called as should have already\n\t    // removed all of the quantifiers.\n\t    throw new NotImplementedException(\n\t\t    \"All quantified sentences should have already been removed.\");\n\t}\n\n\tclass ArgData\n\t{\n\t    public List<Clause> clauses = new List<Clause>();\n\t    public bool negated = false;\n\n\t    public ArgData()\n\t    {\n\t\tclauses.Add(new Clause());\n\t    }\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/logic/fol/Connectors.cs",
    "content": "using System;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public class Connectors\n    {\n\tpublic static readonly String AND = \"AND\";\n\n\tpublic static readonly String OR = \"OR\";\n\n\tpublic static readonly String NOT = \"NOT\";\n\n\tpublic static readonly String IMPLIES = \"=>\";\n\n\tpublic static readonly String BICOND = \"<=>\";\n\n\tpublic static bool isAND(String connector)\n\t{\n\t    return AND.Equals(connector);\n\t}\n\n\tpublic static bool isOR(String connector)\n\t{\n\t    return OR.Equals(connector);\n\t}\n\n\tpublic static bool isNOT(String connector)\n\t{\n\t    return NOT.Equals(connector);\n\t}\n\n\tpublic static bool isIMPLIES(String connector)\n\t{\n\t    return IMPLIES.Equals(connector);\n\t}\n\n\tpublic static bool isBICOND(String connector)\n\t{\n\t    return BICOND.Equals(connector);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/PredicateCollector.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public class PredicateCollector : FOLVisitor\n    {\n\tpublic PredicateCollector()\n\t{\n\n\t}\n\n\tpublic List<Predicate> getPredicates(Sentence s)\n\t{\n\t    return (List<Predicate>)s.accept(this, new List<Predicate>());\n\t}\n\n\tpublic Object visitPredicate(Predicate p, Object arg)\n\t{\n\t    List<Predicate> predicates = (List<Predicate>)arg;\n\t    predicates.Add(p);\n\t    return predicates;\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    return arg;\n\t}\n\n\tpublic Object visitVariable(Variable variable, Object arg)\n\t{\n\t    return arg;\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    return arg;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    return arg;\n\t}\n\n\tpublic Object visitNotSentence(NotSentence sentence, Object arg)\n\t{\n\t    sentence.getNegated().accept(this, arg);\n\t    return arg;\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    sentence.getFirst().accept(this, arg);\n\t    sentence.getSecond().accept(this, arg);\n\t    return arg;\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\t    sentence.getQuantified().accept(this, arg);\n\t    return arg;\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/logic/fol/Quantifiers.cs",
    "content": "using System;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class Quantifiers\n    {\n\tpublic static readonly String FORALL = \"FORALL\";\n\tpublic static readonly String EXISTS = \"EXISTS\";\n\n\tpublic static bool isFORALL(String quantifier)\n\t{\n\t    return FORALL.Equals(quantifier);\n\t}\n\n\tpublic static bool isEXISTS(String quantifier)\n\t{\n\t    return EXISTS.Equals(quantifier);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/StandardizeApart.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.inference.proof;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class StandardizeApart\n    {\n\tprivate VariableCollector variableCollector = null;\n\tprivate SubstVisitor substVisitor = null;\n\n\tpublic StandardizeApart()\n\t{\n\t    variableCollector = new VariableCollector();\n\t    substVisitor = new SubstVisitor();\n\t}\n\n\tpublic StandardizeApart(VariableCollector variableCollector,\n\t\t\tSubstVisitor substVisitor)\n\t{\n\t    this.variableCollector = variableCollector;\n\t    this.substVisitor = substVisitor;\n\t}\n\n\t// Note: see page 327.\n\tpublic StandardizeApartResult standardizeApart(Sentence sentence,\n\t\t\tStandardizeApartIndexical standardizeApartIndexical)\n\t{\n\t    List<Variable> toRename = variableCollector.collectAllVariables(sentence);\n\t    Dictionary<Variable, Term> renameSubstitution = new Dictionary<Variable, Term>();\n\t    Dictionary<Variable, Term> reverseSubstitution = new Dictionary<Variable, Term>();\n\n\t    foreach (Variable var in toRename)\n\t    {\n\t\tVariable v = null;\n\t\tdo\n\t\t{\n\t\t    v = new Variable(standardizeApartIndexical.getPrefix()\n\t\t\t\t    + standardizeApartIndexical.getNextIndex());\n\t\t    // Ensure the new variable name is not already\n\t\t    // accidentally used in the sentence\n\t\t} while (toRename.Contains(v));\n\n\t\trenameSubstitution.Add(var, v);\n\t\treverseSubstitution.Add(v, var);\n\t    }\n\t    Sentence standardized = substVisitor.subst(renameSubstitution,\n\t\t\t    sentence);\n\n\t    return new StandardizeApartResult(sentence, standardized,\n\t\t\t    renameSubstitution, reverseSubstitution);\n\t}\n\n\tpublic Clause standardizeApart(Clause clause,\n\t\t\tStandardizeApartIndexical standardizeApartIndexical)\n\t{\n\n\t    List<Variable> toRename = variableCollector.collectAllVariables(clause);\n\t    Dictionary<Variable, Term> renameSubstitution = new Dictionary<Variable, Term>();\n\n\t    foreach (Variable var in toRename)\n\t    {\n\t\tVariable v = null;\n\t\tdo\n\t\t{\n\t\t    v = new Variable(standardizeApartIndexical.getPrefix()\n\t\t\t\t    + standardizeApartIndexical.getNextIndex());\n\t\t    // Ensure the new variable name is not already\n\t\t    // accidentally used in the sentence\n\t\t} while (toRename.Contains(v));\n\n\t\trenameSubstitution.Add(var, v);\n\t    }\n\n\t    if (renameSubstitution.Count > 0)\n\t    {\n\t\tList<Literal> literals = new List<Literal>();\n\n\t\tforeach (Literal l in clause.getLiterals())\n\t\t{\n\t\t    literals.Add(substVisitor.subst(renameSubstitution, l));\n\t\t}\n\t\tClause renamed = new Clause(literals);\n\t\trenamed.setProofStep(new ProofStepRenaming(renamed, clause\n\t\t\t\t.getProofStep()));\n\t\treturn renamed;\n\t    }\n\t    return clause;\n\t}\n\n\tpublic Chain standardizeApart(Chain chain,\n\t\t\tStandardizeApartIndexical standardizeApartIndexical)\n\t{\n\n\t    List<Variable> toRename = variableCollector.collectAllVariables(chain);\n\t    Dictionary<Variable, Term> renameSubstitution = new Dictionary<Variable, Term>();\n\n\t    foreach (Variable var in toRename)\n\t    {\n\t\tVariable v = null;\n\t\tdo\n\t\t{\n\t\t    v = new Variable(standardizeApartIndexical.getPrefix()\n\t\t\t\t    + standardizeApartIndexical.getNextIndex());\n\t\t    // Ensure the new variable name is not already\n\t\t    // accidentally used in the sentence\n\t\t} while (toRename.Contains(v));\n\n\t\trenameSubstitution.Add(var, v);\n\t    }\n\n\t    if (renameSubstitution.Count > 0)\n\t    {\n\t\tList<Literal> lits = new List<Literal>();\n\n\t\tforeach (Literal l in chain.getLiterals())\n\t\t{\n\t\t    AtomicSentence atom = (AtomicSentence)substVisitor.subst(\n\t\t\t\t    renameSubstitution, l.getAtomicSentence());\n\t\t    lits.Add(l.newInstance(atom));\n\t\t}\n\n\t\tChain renamed = new Chain(lits);\n\n\t\trenamed.setProofStep(new ProofStepRenaming(renamed, chain\n\t\t\t\t.getProofStep()));\n\n\t\treturn renamed;\n\t    }\n\t    return chain;\n\t}\n\n\tpublic Dictionary<Variable, Term> standardizeApart(List<Literal> l1Literals,\n\t\t\tList<Literal> l2Literals,\n\t\t\tStandardizeApartIndexical standardizeApartIndexical)\n\t{\n\t    List<Variable> toRename = new List<Variable>();\n\n\t    foreach (Literal pl in l1Literals)\n\t    {\n\t\ttoRename.AddRange(variableCollector.collectAllVariables(pl\n\t\t\t\t.getAtomicSentence()));\n\t    }\n\t    foreach (Literal nl in l2Literals)\n\t    {\n\t\ttoRename.AddRange(variableCollector.collectAllVariables(nl\n\t\t\t\t.getAtomicSentence()));\n\t    }\n\n\t    Dictionary<Variable, Term> renameSubstitution = new Dictionary<Variable, Term>();\n\n\t    foreach (Variable var in toRename)\n\t    {\n\t\tVariable v = null;\n\t\tdo\n\t\t{\n\t\t    v = new Variable(standardizeApartIndexical.getPrefix()\n\t\t\t\t    + standardizeApartIndexical.getNextIndex());\n\t\t    // Ensure the new variable name is not already\n\t\t    // accidentally used in the sentence\n\t\t} while (toRename.Contains(v));\n\n\t\trenameSubstitution.Add(var, v);\n\t    }\n\n\t    List<Literal> posLits = new List<Literal>();\n\t    List<Literal> negLits = new List<Literal>();\n\n\t    foreach (Literal pl in l1Literals)\n\t    {\n\t\tposLits.Add(substVisitor.subst(renameSubstitution, pl));\n\t    }\n\t    foreach (Literal nl in l2Literals)\n\t    {\n\t\tnegLits.Add(substVisitor.subst(renameSubstitution, nl));\n\t    }\n\n\t    l1Literals.Clear();\n\t    l1Literals.AddRange(posLits);\n\t    l2Literals.Clear();\n\t    l2Literals.AddRange(negLits);\n\n\t    return renameSubstitution;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/StandardizeApartInPlace.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class StandardizeApartInPlace\n    {\n\tprivate static CollectAllVariables _collectAllVariables = new CollectAllVariables();\n\n\tpublic static int standardizeApart(Chain c, int saIdx)\n\t{\n\t    List<Variable> variables = new List<Variable>();\n\t    foreach (Literal l in c.getLiterals())\n\t    {\n\t\tcollectAllVariables(l.getAtomicSentence(), variables);\n\t    }\n\t    return standardizeApart(variables, c, saIdx);\n\t}\n\n\tpublic static int standardizeApart(Clause c, int saIdx)\n\t{\n\t    List<Variable> variables = new List<Variable>();\n\t    foreach (Literal l in c.getLiterals())\n\t    {\n\t\tcollectAllVariables(l.getAtomicSentence(), variables);\n\t    }\n\n\t    return standardizeApart(variables, c, saIdx);\n\t}\n\n\t// PRIVATE METHODS\n\n\tprivate static int standardizeApart(List<Variable> variables, Object expr,\n\t\tint saIdx)\n\t{\n\t    Dictionary<String, int> indexicals = new Dictionary<String, int>();\n\t    foreach (Variable v in variables)\n\t    {\n\t\tif (!indexicals.ContainsKey(v.getIndexedValue()))\n\t\t{\n\t\t    indexicals.Add(v.getIndexedValue(), saIdx++);\n\t\t}\n\t    }\n\t    foreach (Variable v in variables)\n\t    {\n\t\tint i = indexicals[v.getIndexedValue()];\n\t\tif (null == i)\n\t\t{\n\t\t    throw new ApplicationException(\"ERROR: duplicate var=\" + v\n\t\t\t    + \", expr=\" + expr);\n\t\t}\n\t\telse\n\t\t{\n\t\t    v.setIndexical(i);\n\t\t}\n\t    }\n\t    return saIdx;\n\t}\n\n\tprivate static void collectAllVariables(Sentence s, List<Variable> vars)\n\t{\n\t    s.accept(_collectAllVariables, vars);\n\t}\n    }\n\n    class CollectAllVariables : FOLVisitor\n    {\n\tpublic CollectAllVariables()\n\t{\n\n\t}\n\n\tpublic Object visitVariable(Variable var, Object arg)\n\t{\n\t    List<Variable> variables = (List<Variable>)arg;\n\t    variables.Add(var);\n\t    return var;\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\t    // Ensure I collect quantified variables too\n\t    List<Variable> variables = (List<Variable>)arg;\n\t    variables.AddRange(sentence.getVariables());\n\n\t    sentence.getQuantified().accept(this, arg);\n\n\t    return sentence;\n\t}\n\n\tpublic Object visitPredicate(Predicate predicate, Object arg)\n\t{\n\t    foreach (Term t in predicate.getTerms())\n\t    {\n\t\tt.accept(this, arg);\n\t    }\n\t    return predicate;\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    equality.getTerm1().accept(this, arg);\n\t    equality.getTerm2().accept(this, arg);\n\t    return equality;\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    return constant;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    foreach (Term t in function.getTerms())\n\t    {\n\t\tt.accept(this, arg);\n\t    }\n\t    return function;\n\t}\n\n\tpublic Object visitNotSentence(NotSentence sentence, Object arg)\n\t{\n\t    sentence.getNegated().accept(this, arg);\n\t    return sentence;\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    sentence.getFirst().accept(this, arg);\n\t    sentence.getSecond().accept(this, arg);\n\t    return sentence;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/StandardizeApartIndexical.cs",
    "content": "using System;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface StandardizeApartIndexical\n    {\n\tString getPrefix();\n\n\tint getNextIndex();\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/StandardizeApartIndexicalFactory.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * This class ensures unique standardize apart indexicals are created.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class StandardizeApartIndexicalFactory\n    {\n\tprivate static Dictionary<char, int> _assignedIndexicals = new Dictionary<char, int>();\n\n\t// For use in test cases, where predictable behavior is expected.\n\tpublic static void flush()\n\t{\n\t    lock (_assignedIndexicals)\n\t    {\n\t\t_assignedIndexicals.Clear();\n\t    }\n\t}\n\n\tpublic static StandardizeApartIndexical newStandardizeApartIndexical(\n\t\tChar preferredPrefix)\n\t{\n\t    char ch = preferredPrefix;\n\t    if (!(Char.IsLetter(ch) && Char.IsLower(ch)))\n\t    {\n\t\tthrow new ArgumentException(\"Preferred prefix :\"\n\t\t\t\t+ preferredPrefix + \" must be a valid a lower case letter.\");\n\t    }\n\n\t    StringBuilder sb = new StringBuilder();\n\t    lock (_assignedIndexicals)\n\t    {\n\t\tint currentPrefixCnt = -1;\n\t\tif (!_assignedIndexicals.ContainsKey(preferredPrefix))\n\t\t{\n\t\t    currentPrefixCnt = 0;\n\t\t    _assignedIndexicals.Add(preferredPrefix, currentPrefixCnt);\n\t\t}\n\t\telse\n\t\t{\n\t\t    currentPrefixCnt += 1;\n\t\t    _assignedIndexicals[preferredPrefix] = currentPrefixCnt;\n\t\t}\n\n\t\tsb.Append(preferredPrefix);\n\t\tfor (int i = 0; i < currentPrefixCnt; i++)\n\t\t{\n\t\t    sb.Append(preferredPrefix);\n\t\t}\n\t    }\n\n\t    return new StandardizeApartIndexicalImpl(sb.ToString());\n\t}\n    }\n\n    class StandardizeApartIndexicalImpl : StandardizeApartIndexical\n    {\n\tprivate String prefix = null;\n\tprivate int index = 0;\n\n\tpublic StandardizeApartIndexicalImpl(String prefix)\n\t{\n\t    this.prefix = prefix;\n\t}\n\n\t// START-StandardizeApartIndexical\n\tpublic String getPrefix()\n\t{\n\t    return prefix;\n\t}\n\n\tpublic int getNextIndex()\n\t{\n\t    return index++;\n\t}\n\t// END-StandardizeApartIndexical\t\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/StandardizeApartResult.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class StandardizeApartResult\n    {\n\tprivate Sentence originalSentence = null;\n\tprivate Sentence standardized = null;\n\tprivate Dictionary<Variable, Term> forwardSubstitution = null;\n\tprivate Dictionary<Variable, Term> reverseSubstitution = null;\n\n\tpublic StandardizeApartResult(Sentence originalSentence,\n\t\tSentence standardized, Dictionary<Variable, Term> forwardSubstitution,\n\t\tDictionary<Variable, Term> reverseSubstitution)\n\t{\n\t    this.originalSentence = originalSentence;\n\t    this.standardized = standardized;\n\t    this.forwardSubstitution = forwardSubstitution;\n\t    this.reverseSubstitution = reverseSubstitution;\n\t}\n\n\tpublic Sentence getOriginalSentence()\n\t{\n\t    return originalSentence;\n\t}\n\n\tpublic Sentence getStandardized()\n\t{\n\t    return standardized;\n\t}\n\n\tpublic Dictionary<Variable, Term> getForwardSubstitution()\n\t{\n\t    return forwardSubstitution;\n\t}\n\n\tpublic Dictionary<Variable, Term> getReverseSubstitution()\n\t{\n\t    return reverseSubstitution;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/SubstVisitor.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class SubstVisitor : AbstractFOLVisitor\n    {\n\tpublic SubstVisitor()\n\t{\n\n\t}\n\n\t/**\n\t * Note: Refer to Artificial Intelligence A Modern Approach (3rd Edition):\n\t * page 323.\n\t * \n\t * @param theta\n\t *            a substitution.\n\t * @param sentence\n\t *            the substitution has been applied to.\n\t * @return a new Sentence representing the result of applying the\n\t *         substitution theta to aSentence.\n\t * \n\t */\n\tpublic Sentence subst(Dictionary<Variable, Term> theta, Sentence sentence)\n\t{\n\t    return (Sentence)sentence.accept(this, theta);\n\t}\n\n\tpublic Term subst(Dictionary<Variable, Term> theta, Term aTerm)\n\t{\n\t    return (Term)aTerm.accept(this, theta);\n\t}\n\n\tpublic Function subst(Dictionary<Variable, Term> theta, Function function)\n\t{\n\t    return (Function)function.accept(this, theta);\n\t}\n\n\tpublic Literal subst(Dictionary<Variable, Term> theta, Literal literal)\n\t{\n\t    return literal.newInstance((AtomicSentence)literal\n\t\t\t    .getAtomicSentence().accept(this, theta));\n\t}\n\n\tpublic override Object visitVariable(Variable variable, Object arg)\n\t{\n\t    Dictionary<Variable, Term> substitution = (Dictionary<Variable, Term>)arg;\n\t    if (substitution.ContainsKey(variable))\n\t    {\n\t\treturn substitution[variable].copy();\n\t    }\n\t    return variable.copy();\n\t}\n\n\tpublic override Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\n\t    Dictionary<Variable, Term> substitution = (Dictionary<Variable, Term>)arg;\n\n\t    Sentence quantified = sentence.getQuantified();\n\t    Sentence quantifiedAfterSubs = (Sentence)quantified.accept(this, arg);\n\n\t    List<Variable> variables = new List<Variable>();\n\t    foreach (Variable v in sentence.getVariables())\n\t    {\n\t\tif (substitution.ContainsKey(v))\n\t\t{\n\t\t    Term st = substitution[v];\n\t\t    if (st is Variable)\n\t\t    {\n\t\t\t// Only if it is a variable to I replace it, otherwise\n\t\t\t// I drop it.\n\t\t\tvariables.Add((Variable)st.copy());\n\t\t    }\n\t\t}\n\t\telse\n\t\t{\n\t\t    // No substitution for the quantified variable, so\n\t\t    // keep it.\n\t\t    variables.Add((Variable)v.copy());\n\t\t}\n\t    }\n\n\t    // If not variables remaining on the quantifier, then drop it\n\t    if (variables.Count == 0)\n\t    {\n\t\treturn quantifiedAfterSubs;\n\t    }\n\n\t    return new QuantifiedSentence(sentence.getQuantifier(), variables,\n\t\t\t    quantifiedAfterSubs);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/SubsumptionElimination.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 356.<br>\n     * <br>\n     * The subsumption method eliminates all sentences that are subsumed by (that\n     * is, more specific than) an existing sentence in the KB. For example, P(x) is\n     * in the KB, then there is no sense in adding P(A) and even less sense in\n     * adding P(A) V Q(B). Subsumption helps keep the KB small and thus helps keep\n     * the search space small.<br>\n     * <br>\n     * <b>Note:</b> <a\n     * href=\"http://logic.stanford.edu/classes/cs157/2008/lectures/lecture12.pdf\"\n     * >From slide 17.</a> <br>\n     * <br>\n     * Relational Subsumption<br>\n     * <br>\n     * A relational clause &Phi; subsumes &Psi; if and only if there is a\n     * substitution &delta; that, when applied to &Phi;, produces a clause &Phi;'\n     * that is a subset of &Psi;.\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n    public class SubsumptionElimination\n    {\n\t/**\n\t * Returns the clauses that are subsumed by (that is, more specific than) an\n\t * existing clause in the specified set of clauses.\n\t * \n\t * @param clauses\n\t *            a set of clauses in first order logic\n\t * \n\t * @return the clauses that are subsumed by (that is, more specific than) an\n\t *         existing clause in the specified set of clauses.\n\t */\n\tpublic static List<Clause> findSubsumedClauses(List<Clause> clauses)\n\t{\n\t    List<Clause> subsumed = new List<Clause>();\n\n\t    // Group the clauses by their # of literals.\n\t    // Keep track of the min and max # of literals.\n\t    int min = int.MaxValue;\n\t    int max = 0;\n\t    Dictionary<int, List<Clause>> clausesGroupedBySize = new Dictionary<int, List<Clause>>();\n\t    foreach (Clause c in clauses)\n\t    {\n\t\tint size = c.getNumberLiterals();\n\t\tif (size < min)\n\t\t{\n\t\t    min = size;\n\t\t}\n\t\tif (size > max)\n\t\t{\n\t\t    max = size;\n\t\t}\n\t\tList<Clause> cforsize = null;\n\t\tif (clausesGroupedBySize.ContainsKey(size))\n\t\t{\n\t\t    cforsize = clausesGroupedBySize[size];\n\t\t}\n\t\tif (null == cforsize)\n\t\t{\n\t\t    cforsize = new List<Clause>();\n\t\t    clausesGroupedBySize.Add(size, cforsize);\n\t\t}\n\t\tcforsize.Add(c);\n\t    }\n\t    // Check if each smaller clause\n\t    // subsumes any of the larger clauses.\n\t    for (int i = min; i < max; i++)\n\t    {\n\t\tList<Clause> scs = clausesGroupedBySize[i];\n\t\t// Ensure there are clauses with this # of literals\n\t\tif (null != scs)\n\t\t{\n\t\t    for (int j = i + 1; j <= max; j++)\n\t\t    {\n\n\t\t\t// Ensure there are clauses with this # of literals\n\t\t\tif (clausesGroupedBySize.ContainsKey(j))\n\t\t\t{\n\t\t\t    List<Clause> lcs = clausesGroupedBySize[j];\n\t\t\t    foreach (Clause sc in scs)\n\t\t\t    {\n\t\t\t\t// Don't bother checking clauses\n\t\t\t\t// that are already subsumed.\n\t\t\t\tif (!subsumed.Contains(sc))\n\t\t\t\t{\n\t\t\t\t    foreach (Clause lc in lcs)\n\t\t\t\t    {\n\t\t\t\t\tif (!subsumed.Contains(lc))\n\t\t\t\t\t{\n\t\t\t\t\t    if (sc.subsumes(lc))\n\t\t\t\t\t    {\n\t\t\t\t\t\tsubsumed.Add(lc);\n\t\t\t\t\t    }\n\t\t\t\t\t}\n\t\t\t\t    }\n\t\t\t\t}\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t    return subsumed;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/Unifier.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 9.1, page\n     * 328.<br>\n     * <br>\n     * \n     * <pre>\n     * function UNIFY(x, y, theta) returns a substitution to make x and y identical\n     *   inputs: x, a variable, constant, list, or compound\n     *           y, a variable, constant, list, or compound\n     *           theta, the substitution built up so far (optional, defaults to empty)\n     *           \n     *   if theta = failure then return failure\n     *   else if x = y the return theta\n     *   else if VARIABLE?(x) then return UNIVY-VAR(x, y, theta)\n     *   else if VARIABLE?(y) then return UNIFY-VAR(y, x, theta)\n     *   else if COMPOUND?(x) and COMPOUND?(y) then\n     *       return UNIFY(x.ARGS, y.ARGS, UNIFY(x.OP, y.OP, theta))\n     *   else if LIST?(x) and LIST?(y) then\n     *       return UNIFY(x.REST, y.REST, UNIFY(x.FIRST, y.FIRST, theta))\n     *   else return failure\n     *   \n     * ---------------------------------------------------------------------------------------------------\n     * \n     * function UNIFY-VAR(var, x, theta) returns a substitution\n     *            \n     *   if {var/val} E theta then return UNIFY(val, x, theta)\n     *   else if {x/val} E theta then return UNIFY(var, val, theta)\n     *   else if OCCUR-CHECK?(var, x) then return failure\n     *   else return add {var/x} to theta\n     * </pre>\n     * \n     * Figure 9.1 The unification algorithm. The algorithm works by comparing the\n     * structures of the inputs, elements by element. The substitution theta that is\n     * the argument to UNIFY is built up along the way and is used to make sure that\n     * later comparisons are consistent with bindings that were established earlier.\n     * In a compound expression, such as F(A, B), the OP field picks out the\n     * function symbol F and the ARGS field picks out the argument list (A, B).\n     * \n     * @author Ciaran O'Reilly\n     * @author Ravi Mohan\n     * @author Mike Stampone\n     * \n     */\n    public class Unifier\n    {\n\tprivate static SubstVisitor _substVisitor = new SubstVisitor();\n        private VariableCollector _variableCollector;\n\n        public Unifier()\n\t{\n\n\t}\n\n\t/**\n\t * Returns a Dictionary<Variable, Term> representing the substitution (i.e. a set\n\t * of variable/term pairs) or null which is used to indicate a failure to\n\t * unify.\n\t * \n\t * @param x\n\t *            a variable, constant, list, or compound\n\t * @param y\n\t *            a variable, constant, list, or compound\n\t * \n\t * @return a Dictionary<Variable, Term> representing the substitution (i.e. a set\n\t *         of variable/term pairs) or null which is used to indicate a\n\t *         failure to unify.\n\t */\n\tpublic Dictionary<Variable, Term> unify(FOLNode x, FOLNode y)\n\t{\n\t    return unify(x, y, new Dictionary<Variable, Term>());\n\t}\n\n\t/**\n\t * Returns a Dictionary<Variable, Term> representing the substitution (i.e. a set\n\t * of variable/term pairs) or null which is used to indicate a failure to\n\t * unify.\n\t * \n\t * @param x\n\t *            a variable, constant, list, or compound\n\t * @param y\n\t *            a variable, constant, list, or compound\n\t * @param theta\n\t *            the substitution built up so far\n\t * \n\t * @return a Dictionary<Variable, Term> representing the substitution (i.e. a set\n\t *         of variable/term pairs) or null which is used to indicate a\n\t *         failure to unify.\n\t */\n\tpublic Dictionary<Variable, Term> unify(FOLNode x, FOLNode y,\n\t\tDictionary<Variable, Term> theta)\n\t{\n\t    // if theta = failure then return failure\n\t    if (theta == null)\n\t    {\n\t\treturn null;\n\t    }\n\t    else if (x.Equals(y))\n\t    {\n\t\t// else if x = y then return theta\n\t\treturn theta;\n\t    }\n\t    else if (x is Variable)\n\t    {\n\t\t// else if VARIABLE?(x) then return UNIVY-VAR(x, y, theta)\n\t\treturn unifyVar((Variable)x, y, theta);\n\t    }\n\t    else if (y is Variable)\n\t    {\n\t\t// else if VARIABLE?(y) then return UNIFY-VAR(y, x, theta)\n\t\treturn unifyVar((Variable)y, x, theta);\n\t    }\n\t    else if (isCompound(x) && isCompound(y))\n\t    {\n\t\t// else if COMPOUND?(x) and COMPOUND?(y) then\n\t\t// return UNIFY(x.ARGS, y.ARGS, UNIFY(x.OP, y.OP, theta))\n\t\treturn unify(args(x), args(y), unifyOps(op(x), op(y), theta));\n\t    }\n\t    else\n\t    {\n\t\t// else return failure\n\t\treturn null;\n\t    }\n\t}\n\n\t/**\n\t * Returns a Dictionary<Variable, Term> representing the substitution (i.e. a set\n\t * of variable/term pairs) or null which is used to indicate a failure to\n\t * unify.\n\t * \n\t * @param x\n\t *            a variable, constant, list, or compound\n\t * @param y\n\t *            a variable, constant, list, or compound\n\t * @param theta\n\t *            the substitution built up so far\n\t * \n\t * @return a Dictionary<Variable, Term> representing the substitution (i.e. a set\n\t *         of variable/term pairs) or null which is used to indicate a\n\t *         failure to unify.\n\t */\n\t// else if LIST?(x) and LIST?(y) then\n\t// return UNIFY(x.REST, y.REST, UNIFY(x.FIRST, y.FIRST, theta))\n\tpublic Dictionary<Variable, Term> unify(List<FOLNode> x,\n\t       List<FOLNode> y, Dictionary<Variable, Term> theta)\n\t{\n\t    if (theta == null)\n\t    {\n\t\treturn null;\n\t    }\n\t    else if (x.Count != y.Count)\n\t    {\n\t\treturn null;\n\t    }\n\t    else if (x.Count == 0 && y.Count == 0)\n\t    {\n\t\treturn theta;\n\t    }\n\t    else if (x.Count == 1 && y.Count == 1)\n\t    {\n\t\treturn unify(x[0], y[0], theta);\n\t    }\n\t    else\n\t    {\n\t\treturn unify(x.Skip(1).ToList<FOLNode>(), y.Skip(1).ToList<FOLNode>(), unify(\n\t\t\tx[0], y[0], theta));\n\t    }\n\t}\n\n\t// PROTECTED METHODS\n\n\t// Note: You can subclass and override this method in order\n\t// to re-implement the OCCUR-CHECK?() to always\n\t// return false if you want that to be the default\n\t// behavior, as is the case with Prolog.\n\tprotected bool occurCheck(Dictionary<Variable, Term> theta, Variable var,\n\t       FOLNode x)\n\t{\n\t    if (x is Function)\n\t    {\n\t\tList<Variable> varsToCheck = _variableCollector\n\t\t\t.collectAllVariables((Function)x);\n\t\tif (varsToCheck.Contains(var))\n\t\t{\n\t\t    return true;\n\t\t}\n\n\t\t// Now need to check if cascading will cause occurs to happen\n\t\t// e.g.\n\t\t// Loves(SF1(v2),v2)\n\t\t// Loves(v3,SF0(v3))\n\t\t// or\n\t\t// P(v1,SF0(v1),SF0(v1))\n\t\t// P(v2,SF0(v2),v2 )\n\t\t// or\n\t\t// P(v1, F(v2),F(v2),F(v2),v1, F(F(v1)),F(F(F(v1))),v2)\n\t\t// P(F(v3),v4, v5, v6, F(F(v5)),v4, F(v3), F(F(v5)))\n\t\treturn cascadeOccurCheck(theta, var, varsToCheck,\n\t\t\tnew List<Variable>(varsToCheck));\n\t    }\n\t    return false;\n\t}\n\n\t// PRIVATE METHODS\n\n\t/**\n         * <code>\n         * function UNIFY-VAR(var, x, theta) returns a substitution\n         *   inputs: var, a variable\n         *       x, any expression\n         *       theta, the substitution built up so far\n         * </code>\n         */\n\tprivate Dictionary<Variable, Term> unifyVar(Variable var, FOLNode x,\n\t\tDictionary<Variable, Term> theta)\n\t{\n\n\t    if (!(x is Term))\n\t    {\n\t\treturn null;\n\t    }\n\t    else if (theta.ContainsKey(var))\n\t    {\n\t\t// if {var/val} E theta then return UNIFY(val, x, theta)\n\t\treturn unify(theta[var], x, theta);\n\t    }\n\t    else if (theta.Keys.Contains(x))\n\t    {\n\t\t// else if {x/val} E theta then return UNIFY(var, val, theta)\n\t\treturn unify(var, (FOLNode)theta[(Variable)x], theta);\n\t    }\n\t    else if (occurCheck(theta, var, x))\n\t    {\n\t\t// else if OCCUR-CHECK?(var, x) then return failure\n\t\treturn null;\n\t    }\n\t    else\n\t    {\n\t\t// else return add {var/x} to theta\n\t\tcascadeSubstitution(theta, var, (Term)x);\n\t\treturn theta;\n\t    }\n\t}\n\n\tprivate Dictionary<Variable, Term> unifyOps(String x, String y,\n\t\tDictionary<Variable, Term> theta)\n\t{\n\t    if (theta == null)\n\t    {\n\t\treturn null;\n\t    }\n\t    else if (x.Equals(y))\n\t    {\n\t\treturn theta;\n\t    }\n\t    else\n\t    {\n\t\treturn null;\n\t    }\n\t}\n\n\tprivate List<FOLNode> args(FOLNode x)\n\t{\n\t    return x.getArgs();\n\t}\n\n\tprivate String op(FOLNode x)\n\t{\n\t    return x.getSymbolicName();\n\t}\n\n\tprivate bool isCompound(FOLNode x)\n\t{\n\t    return x.isCompound();\n\t}\n\n\tprivate bool cascadeOccurCheck(Dictionary<Variable, Term> theta, Variable var,\n\t       List<Variable> varsToCheck, List<Variable> varsCheckedAlready)\n\t{\n\t    // Want to check if any of the variable to check end up\n\t    // looping back around on the new variable.\n\t    List<Variable> nextLevelToCheck = new List<Variable>();\n\t    foreach (Variable v in varsToCheck)\n\t    {\n\t\tTerm t = null;\n\t\tif (theta.ContainsKey(v))\n\t\t{\n\t\t    t = theta[v];\n\t\t}\n\t\tif (null == t)\n\t\t{\n\t\t    // Variable may not be a key so skip\n\t\t    continue;\n\t\t}\n\t\tif (t.Equals(var))\n\t\t{\n\t\t    // e.g.\n\t\t    // v1=v2\n\t\t    // v2=SFO(v1)\n\t\t    return true;\n\t\t}\n\t\telse if (t is Function)\n\t\t{\n\t\t    // Need to ensure the function this variable\n\t\t    // is to be replaced by does not contain var.\n\t\t    List<Variable> indirectvars = _variableCollector\n\t\t\t    .collectAllVariables(t);\n\t\t    if (indirectvars.Contains(var))\n\t\t    {\n\t\t\treturn true;\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\t// Determine the next cascade/level\n\t\t\t// of variables to check for looping\n\t\t\tforeach (Variable iv in indirectvars)\n\t\t\t{\n\t\t\t    if (!varsCheckedAlready.Contains(iv))\n\t\t\t    {\n\t\t\t\tnextLevelToCheck.Add(iv);\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t    if (nextLevelToCheck.Count > 0)\n\t    {\n\t\tvarsCheckedAlready.AddRange(nextLevelToCheck);\n\t\treturn cascadeOccurCheck(theta, var, nextLevelToCheck,\n\t\t\tvarsCheckedAlready);\n\t    }\n\t    return false;\n\t}\n\n\t// See:\n\t// http://logic.stanford.edu/classes/cs157/2008/miscellaneous/faq.html#jump165\n\t// for need for this.\n\tprivate void cascadeSubstitution(Dictionary<Variable, Term> theta, Variable var,\n\t\tTerm x)\n\t{\n\t    theta.Add(var, x);\n\t    List<Variable> thetaKeys = theta.Keys.ToList<Variable>();\n\t    foreach (Variable v in thetaKeys)\n\t    {\n\t\tTerm t = theta[v];\n\t\tif (theta.ContainsKey(v))\n\t\t{\n\t\t    theta[v] = _substVisitor.subst(theta, t);\n\t\t}\n\t\telse\n\t\t{\n\t\t    theta.Add(v, _substVisitor.subst(theta, t));\n\t\t}\n\t    }\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/logic/fol/VariableCollector.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.parsing.ast;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class VariableCollector : FOLVisitor\n    {\n\tpublic VariableCollector()\n\t{\n\n\t}\n\n\n\t// Note: The set guarantees the order in which they were\n\t// found.\n\tpublic List<Variable> collectAllVariables(Sentence sentence)\n\t{\n\t    List<Variable> variables = new List<Variable>();\n\n\t    sentence.accept(this, variables);\n\n\t    return variables;\n\t}\n\n\tpublic List<Variable> collectAllVariables(Term aTerm)\n\t{\n\t    List<Variable> variables = new List<Variable>();\n\n\t    aTerm.accept(this, variables);\n\n\t    return variables;\n\t}\n\n\tpublic List<Variable> collectAllVariables(Clause aClause)\n\t{\n\t    List<Variable> variables = new List<Variable>();\n\n\t    foreach (Literal l in aClause.getLiterals())\n\t    {\n\t\tl.getAtomicSentence().accept(this, variables);\n\t    }\n\n\t    return variables;\n\t}\n\n\tpublic List<Variable> collectAllVariables(Chain aChain)\n\t{\n\t    List<Variable> variables = new List<Variable>();\n\n\t    foreach (Literal l in aChain.getLiterals())\n\t    {\n\t\tl.getAtomicSentence().accept(this, variables);\n\t    }\n\n\t    return variables;\n\t}\n\n\tpublic Object visitVariable(Variable var, Object arg)\n\t{\n\t    List<Variable> variables = (List<Variable>)arg;\n\t    variables.Add(var);\n\t    return var;\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\t    // Ensure I collect quantified variables too\n\t    List<Variable> variables = (List<Variable>)arg;\n\t    variables.AddRange(sentence.getVariables());\n\n\t    sentence.getQuantified().accept(this, arg);\n\n\t    return sentence;\n\t}\n\n\tpublic Object visitPredicate(Predicate predicate, Object arg)\n\t{\n\t    foreach (Term t in predicate.getTerms())\n\t    {\n\t\tt.accept(this, arg);\n\t    }\n\t    return predicate;\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    equality.getTerm1().accept(this, arg);\n\t    equality.getTerm2().accept(this, arg);\n\t    return equality;\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    return constant;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    foreach (Term t in function.getTerms())\n\t    {\n\t\tt.accept(this, arg);\n\t    }\n\t    return function;\n\t}\n\n\tpublic Object visitNotSentence(NotSentence sentence, Object arg)\n\t{\n\t    sentence.getNegated().accept(this, arg);\n\t    return sentence;\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    sentence.getFirst().accept(this, arg);\n\t    sentence.getSecond().accept(this, arg);\n\t    return sentence;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/domain/DomainFactory.cs",
    "content": "using System;\n\nnamespace aima.core.logic.fol.domain\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public class DomainFactory\n    {\n\tpublic static FOLDomain crusadesDomain()\n\t{\n\t    FOLDomain domain = new FOLDomain();\n\t    domain.addConstant(\"John\");\n\t    domain.addConstant(\"Richard\");\n\t    domain.addConstant(\"England\");\n\t    domain.addConstant(\"Saladin\");\n\t    domain.addConstant(\"Crown\");\n\n\t    domain.addFunction(\"LeftLegOf\");\n\t    domain.addFunction(\"BrotherOf\");\n\t    domain.addFunction(\"EnemyOf\");\n\t    domain.addFunction(\"LegsOf\");\n\n\t    domain.addPredicate(\"King\");\n\t    return domain;\n\t}\n\n\tpublic static FOLDomain knowsDomain()\n\t{\n\t    FOLDomain domain = new FOLDomain();\n\t    domain.addConstant(\"John\");\n\t    domain.addConstant(\"Jane\");\n\t    domain.addConstant(\"Bill\");\n\t    domain.addConstant(\"Elizabeth\");\n\t    domain.addFunction(\"Mother\");\n\t    domain.addPredicate(\"Knows\");\n\n\t    return domain;\n\t}\n\n\tpublic static FOLDomain weaponsDomain()\n\t{\n\n\t    FOLDomain domain = new FOLDomain();\n\t    domain.addConstant(\"West\");\n\t    domain.addConstant(\"America\");\n\t    domain.addConstant(\"M1\");\n\t    domain.addConstant(\"Nono\");\n\t    domain.addPredicate(\"American\");\n\t    domain.addPredicate(\"Weapon\");\n\t    domain.addPredicate(\"Sells\");\n\t    domain.addPredicate(\"Hostile\");\n\t    domain.addPredicate(\"Criminal\");\n\t    domain.addPredicate(\"Missile\");\n\t    domain.addPredicate(\"Owns\");\n\t    domain.addPredicate(\"Enemy\");\n\n\t    return domain;\n\t}\n\n\tpublic static FOLDomain kingsDomain()\n\t{\n\t    FOLDomain domain = new FOLDomain();\n\t    domain.addConstant(\"John\");\n\t    domain.addConstant(\"Richard\");\n\t    domain.addPredicate(\"King\");\n\t    domain.addPredicate(\"Greedy\");\n\t    domain.addPredicate(\"Evil\");\n\n\t    return domain;\n\t}\n\n\tpublic static FOLDomain lovesAnimalDomain()\n\t{\n\t    FOLDomain domain = new FOLDomain();\n\t    domain.addPredicate(\"Animal\");\n\t    domain.addPredicate(\"Loves\");\n\t    domain.addPredicate(\"Kills\");\n\t    domain.addPredicate(\"Cat\");\n\t    domain.addConstant(\"Jack\");\n\t    domain.addConstant(\"Tuna\");\n\t    domain.addConstant(\"Curiosity\");\n\n\t    return domain;\n\t}\n\n\tpublic static FOLDomain ringOfThievesDomain()\n\t{\n\t    FOLDomain domain = new FOLDomain();\n\t    domain.addPredicate(\"Parent\");\n\t    domain.addPredicate(\"Caught\");\n\t    domain.addPredicate(\"Friend\");\n\t    domain.addPredicate(\"Skis\");\n\t    domain.addConstant(\"Mike\");\n\t    domain.addConstant(\"Joe\");\n\t    domain.addConstant(\"Janet\");\n\t    domain.addConstant(\"Nancy\");\n\t    domain.addConstant(\"Ernie\");\n\t    domain.addConstant(\"Bert\");\n\t    domain.addConstant(\"Red\");\n\t    domain.addConstant(\"Drew\");\n\n\t    return domain;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/domain/FOLDomain.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.util;\n\nnamespace aima.core.logic.fol.domain\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class FOLDomain\n    {\n\tprivate HashSet<String> constants, functions, predicates;\n\tprivate int skolemConstantIndexical = 0;\n\tprivate int skolemFunctionIndexical = 0;\n\tprivate int answerLiteralIndexical = 0;\n\tprivate List<FOLDomainListener> listeners = new List<FOLDomainListener>();\n\n\tpublic FOLDomain()\n\t{\n\t    this.constants = new HashSet<String>();\n\t    this.functions = new HashSet<String>();\n\t    this.predicates = new HashSet<String>();\n\t}\n\n\tpublic FOLDomain(FOLDomain toCopy): this(toCopy.getConstants(), toCopy.getFunctions(), toCopy\n\t\t\t    .getPredicates())\n\t{\n\t    \n\t}\n\n\tpublic FOLDomain(HashSet<String> constants, HashSet<String> functions,\n\t\t\tHashSet<String> predicates)\n\t{\n\t    this.constants = new HashSet<String>(constants);\n\t    this.functions = new HashSet<String>(functions);\n\t    this.predicates = new HashSet<String>(predicates);\n\t}\n\n\tpublic HashSet<String> getConstants()\n\t{\n\t    return constants;\n\t}\n\n\tpublic HashSet<String> getFunctions()\n\t{\n\t    return functions;\n\t}\n\n\tpublic HashSet<String> getPredicates()\n\t{\n\t    return predicates;\n\t}\n\n\tpublic void addConstant(String constant)\n\t{\n\t    constants.Add(constant);\n\t}\n\n\tpublic String addSkolemConstant()\n\t{\n\n\t    String sc = null;\n\t    do\n\t    {\n\t\tsc = \"SC\" + (skolemConstantIndexical++);\n\t    } while (constants.Contains(sc) || functions.Contains(sc)\n\t\t\t    || predicates.Contains(sc));\n\n\t    addConstant(sc);\n\t    notifyFOLDomainListeners(new FOLDomainSkolemConstantAddedEvent(this, sc));\n\n\t    return sc;\n\t}\n\n\tpublic void addFunction(String function)\n\t{\n\t    functions.Add(function);\n\t}\n\n\tpublic String addSkolemFunction()\n\t{\n\t    String sf = null;\n\t    do\n\t    {\n\t\tsf = \"SF\" + (skolemFunctionIndexical++);\n\t    } while (constants.Contains(sf) || functions.Contains(sf)\n\t\t\t    || predicates.Contains(sf));\n\n\t    addFunction(sf);\n\t    notifyFOLDomainListeners(new FOLDomainSkolemFunctionAddedEvent(this, sf));\n\n\t    return sf;\n\t}\n\n\tpublic void addPredicate(String predicate)\n\t{\n\t    predicates.Add(predicate);\n\t}\n\n\tpublic String addAnswerLiteral()\n\t{\n\t    String al = null;\n\t    do\n\t    {\n\t\tal = \"Answer\" + (answerLiteralIndexical++);\n\t    } while (constants.Contains(al) || functions.Contains(al)\n\t\t\t    || predicates.Contains(al));\n\n\t    addPredicate(al);\n\t    notifyFOLDomainListeners(new FOLDomainAnswerLiteralAddedEvent(this, al));\n\n\t    return al;\n\t}\n\n\tpublic void addFOLDomainListener(FOLDomainListener listener)\n\t{\n\t    lock (listeners) \n\t    {\n\t\tif (!listeners.Contains(listener))\n\t\t{\n\t\t    listeners.Add(listener);\n\t\t}\n\t    }\n\t}\n\n\tpublic void removeFOLDomainListener(FOLDomainListener listener)\n\t{\n\t    lock (listeners) \n\t    {\n\t\tlisteners.Remove(listener);\n\t    }\n\t}\n\n\t// PRIVATE METHODS\n\t\n\tprivate void notifyFOLDomainListeners(FOLDomainEvent evt)\n\t{\n\t    lock (listeners)\n\t    {\n\t\tforeach (FOLDomainListener l in listeners)\n\t\t{\n\t\t    evt.notifyListener(l);\n\t\t}\n\t    }\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/domain/FOLDomainAnswerLiteralAddedEvent.cs",
    "content": "using System;\n\nnamespace aima.core.logic.fol.domain\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class FOLDomainAnswerLiteralAddedEvent : FOLDomainEvent\n    {\n\tprivate static readonly long serialVersionUID = 1L;\n\n\tprivate String answerLiteralName;\n\n\tpublic FOLDomainAnswerLiteralAddedEvent(Object source,\n\t\t\tString answerLiteralName): base(source)\n\t{\t    \n\t    this.answerLiteralName = answerLiteralName;\n\t}\n\n\tpublic String getAnswerLiteralNameName()\n\t{\n\t    return answerLiteralName;\n\t}\n\t\t\n\tpublic override void notifyListener(FOLDomainListener listener)\n\t{\n\t    listener.answerLiteralNameAdded(this);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/domain/FOLDomainEvent.cs",
    "content": "using System;\n\nnamespace aima.core.logic.fol.domain\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public abstract class FOLDomainEvent\n    {\n\tprivate static readonly long serialVersionUID = 1L;\n\n\tpublic FOLDomainEvent(Object source)\n\t{\n\t    \n\t}\n\n\tpublic abstract void notifyListener(FOLDomainListener listener);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/domain/FOLDomainListener.cs",
    "content": "using System;\n\nnamespace aima.core.logic.fol.domain\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface FOLDomainListener\n    {\n\tvoid skolemConstantAdded(FOLDomainSkolemConstantAddedEvent _event);\n\n\tvoid skolemFunctionAdded(FOLDomainSkolemFunctionAddedEvent _event);\n\n\tvoid answerLiteralNameAdded(FOLDomainAnswerLiteralAddedEvent _event);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/domain/FOLDomainSkolemConstantAddedEvent.cs",
    "content": "using System;\n\nnamespace aima.core.logic.fol.domain\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class FOLDomainSkolemConstantAddedEvent : FOLDomainEvent\n    {\n\tprivate static readonly long serialVersionUID = 1L;\n\n\tprivate String skolemConstantName;\n\n\tpublic FOLDomainSkolemConstantAddedEvent(Object source,\n\t\t\tString skolemConstantName): base(source)\n\t{\t    \n\t    this.skolemConstantName = skolemConstantName;\n\t}\n\n\tpublic String getSkolemConstantName()\n\t{\n\t    return skolemConstantName;\n\t}\n\t\n\tpublic override void notifyListener(FOLDomainListener listener)\n\t{\n\t    listener.skolemConstantAdded(this);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/domain/FOLDomainSkolemFunctionAddedEvent.cs",
    "content": "using System;\n\nnamespace aima.core.logic.fol.domain\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class FOLDomainSkolemFunctionAddedEvent : FOLDomainEvent\n    {\n\tprivate static readonly long serialVersionUID = 1L;\n\n\tprivate String skolemFunctionName;\n\n\tpublic FOLDomainSkolemFunctionAddedEvent(Object source,\n\t\t\tString skolemFunctionName): base(source)\n\t{\t    \n\t    this.skolemFunctionName = skolemFunctionName;\n\t}\n\n\tpublic String getSkolemConstantName()\n\t{\n\t    return skolemFunctionName;\n\t}\n\t\n\tpublic override void notifyListener(FOLDomainListener listener)\n\t{\n\t    listener.skolemFunctionAdded(this);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/AbstractModulation.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * Abstract base class for Demodulation and Paramodulation algorithms.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public abstract class AbstractModulation\n    {\n\t// PROTECTED ATTRIBUTES\n\tprotected VariableCollector variableCollector = new VariableCollector();\n\tprotected Unifier unifier = new Unifier();\n\tprotected SubstVisitor substVisitor = new SubstVisitor();\n\n\t// PROTECTED METODS\t\n\tpublic abstract bool isValidMatch(Term toMatch,\n\t\tList<Variable> toMatchVariables, Term possibleMatch,\n\t\tDictionary<Variable, Term> substitution);\n\n\tprotected IdentifyCandidateMatchingTerm getMatchingSubstitution(\n\t\tTerm toMatch, AtomicSentence expression)\n\t{\n\n\t    IdentifyCandidateMatchingTerm icm = new IdentifyCandidateMatchingTerm(\n\t\t    toMatch, expression, this);\n\n\t    if (icm.isMatch())\n\t    {\n\t\treturn icm;\n\t    }\n\t    // indicates no match\n\t    return null;\n\t}\n\n\tprotected class IdentifyCandidateMatchingTerm : FOLVisitor\n\t{\n\t    private Term toMatch = null;\n\t    private List<Variable> toMatchVariables = null;\n\t    private Term matchingTerm = null;\n\t    private Dictionary<Variable, Term> substitution = null;\n\t    private AbstractModulation abstractModulation;\n\n\t    public IdentifyCandidateMatchingTerm(Term toMatch,\n\t\t    AtomicSentence expression, AbstractModulation abstractModulation)\n\t    {\n\t\tthis.abstractModulation = abstractModulation;\n\t\tthis.toMatch = toMatch;\n\t\tthis.toMatchVariables = abstractModulation.variableCollector\n\t\t\t.collectAllVariables(toMatch);\n\n\t\texpression.accept(this, null);\n\t    }\n\n\t    public bool isMatch()\n\t    {\n\t\treturn null != matchingTerm;\n\t    }\n\n\t    public Term getMatchingTerm()\n\t    {\n\t\treturn matchingTerm;\n\t    }\n\n\t    public Dictionary<Variable, Term> getMatchingSubstitution()\n\t    {\n\t\treturn substitution;\n\t    }\n\t    \n\t    // START-FOLVisitor\n\t    public Object visitPredicate(Predicate p, Object arg)\n\t    {\n\t\tforeach (Term t in p.getArgs())\n\t\t{\n\t\t    // Finish processing if have found a match\n\t\t    if (null != matchingTerm)\n\t\t    {\n\t\t\tbreak;\n\t\t    }\n\t\t    t.accept(this, null);\n\t\t}\n\t\treturn p;\n\t    }\n\n\t    public Object visitTermEquality(TermEquality equality, Object arg)\n\t    {\n\t\tforeach (Term t in equality.getArgs())\n\t\t{\n\t\t    // Finish processing if have found a match\n\t\t    if (null != matchingTerm)\n\t\t    {\n\t\t\tbreak;\n\t\t    }\n\t\t    t.accept(this, null);\n\t\t}\n\t\treturn equality;\n\t    }\n\n\t    public Object visitVariable(Variable variable, Object arg)\n\t    {\n\n\t\tif (null != (substitution = abstractModulation.unifier.unify(toMatch, variable)))\n\t\t{\n\t\t    if (abstractModulation.isValidMatch(toMatch, toMatchVariables, variable,\n\t\t\t    substitution))\n\t\t    {\n\t\t\tmatchingTerm = variable;\n\t\t    }\n\t\t}\n\t\treturn variable;\n\t    }\n\n\t    public Object visitConstant(Constant constant, Object arg)\n\t    {\n\t\tif (null != (substitution = abstractModulation.unifier.unify(toMatch, constant)))\n\t\t{\n\t\t    if (abstractModulation.isValidMatch(toMatch, toMatchVariables, constant,\n\t\t\t    substitution))\n\t\t    {\n\t\t\tmatchingTerm = constant;\n\t\t    }\n\t\t}\n\t\treturn constant;\n\t    }\n\n\t    public Object visitFunction(Function function, Object arg)\n\t    {\n\t\tif (null != (substitution = abstractModulation.unifier.unify(toMatch, function)))\n\t\t{\n\t\t    if (abstractModulation.isValidMatch(toMatch, toMatchVariables, function,\n\t\t\t    substitution))\n\t\t    {\n\t\t\tmatchingTerm = function;\n\t\t    }\n\t\t}\n\n\t\tif (null == matchingTerm)\n\t\t{\n\t\t    // Try the Function's arguments\n\t\t    foreach (Term t in function.getArgs())\n\t\t    {\n\t\t\t// Finish processing if have found a match\n\t\t\tif (null != matchingTerm)\n\t\t\t{\n\t\t\t    break;\n\t\t\t}\n\t\t\tt.accept(this, null);\n\t\t    }\n\t\t}\n\t\treturn function;\n\t    }\n\n\t    public Object visitNotSentence(NotSentence sentence, Object arg)\n\t    {\n\t\tthrow new NotImplementedException(\n\t\t\t\"visitNotSentence() should not be called.\");\n\t    }\n\n\t    public Object visitConnectedSentence(ConnectedSentence sentence,\n\t\t    Object arg)\n\t    {\n\t\tthrow new NotImplementedException(\n\t\t\t\"visitConnectedSentence() should not be called.\");\n\t    }\n\n\t    public Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\t    Object arg)\n\t    {\n\t\tthrow new NotImplementedException(\n\t\t\t\"visitQuantifiedSentence() should not be called.\");\n\t    }\n\t    // END-FOLVisitor\n\t}\n\n\tprotected class ReplaceMatchingTerm : FOLVisitor\n\t{\n\t    private Term toReplace = null;\n\t    private Term replaceWith = null;\n\t    private bool replaced = false;\n\n\t    public ReplaceMatchingTerm()\n\t    {\n\t    }\n\n\t    public AtomicSentence replace(AtomicSentence expression,\n\t\t    Term toReplace, Term replaceWith)\n\t    {\n\t\tthis.toReplace = toReplace;\n\t\tthis.replaceWith = replaceWith;\n\n\t\treturn (AtomicSentence)expression.accept(this, null);\n\t    }\n\n\t    //\n\t    // START-FOLVisitor\n\t    public Object visitPredicate(Predicate p, Object arg)\n\t    {\n\t\tList<Term> newTerms = new List<Term>();\n\t\tforeach (Term t in p.getTerms())\n\t\t{\n\t\t    Term subsTerm = (Term)t.accept(this, arg);\n\t\t    newTerms.Add(subsTerm);\n\t\t}\n\t\treturn new Predicate(p.getPredicateName(), newTerms);\n\t    }\n\n\t    public Object visitTermEquality(TermEquality equality, Object arg)\n\t    {\n\t\tTerm newTerm1 = (Term)equality.getTerm1().accept(this, arg);\n\t\tTerm newTerm2 = (Term)equality.getTerm2().accept(this, arg);\n\t\treturn new TermEquality(newTerm1, newTerm2);\n\t    }\n\n\t    public Object visitVariable(Variable variable, Object arg)\n\t    {\n\t\tif (!replaced)\n\t\t{\n\t\t    if (toReplace.Equals(variable))\n\t\t    {\n\t\t\treplaced = true;\n\t\t\treturn replaceWith;\n\t\t    }\n\t\t}\n\t\treturn variable;\n\t    }\n\n\t    public Object visitConstant(Constant constant, Object arg)\n\t    {\n\t\tif (!replaced)\n\t\t{\n\t\t    if (toReplace.Equals(constant))\n\t\t    {\n\t\t\treplaced = true;\n\t\t\treturn replaceWith;\n\t\t    }\n\t\t}\n\t\treturn constant;\n\t    }\n\n\t    public Object visitFunction(Function function, Object arg)\n\t    {\n\t\tif (!replaced)\n\t\t{\n\t\t    if (toReplace.Equals(function))\n\t\t    {\n\t\t\treplaced = true;\n\t\t\treturn replaceWith;\n\t\t    }\n\t\t}\n\n\t\tList<Term> newTerms = new List<Term>();\n\t\tforeach (Term t in function.getTerms())\n\t\t{\n\t\t    Term subsTerm = (Term)t.accept(this, arg);\n\t\t    newTerms.Add(subsTerm);\n\t\t}\n\t\treturn new Function(function.getFunctionName(), newTerms);\n\t    }\n\n\t    public Object visitNotSentence(NotSentence sentence, Object arg)\n\t    {\n\t\tthrow new NotImplementedException(\n\t\t\t\"visitNotSentence() should not be called.\");\n\t    }\n\n\t    public Object visitConnectedSentence(ConnectedSentence sentence,\n\t\t    Object arg)\n\t    {\n\t\tthrow new NotImplementedException(\n\t\t\t\"visitConnectedSentence() should not be called.\");\n\t    }\n\n\t    public Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\t    Object arg)\n\t    {\n\t\tthrow new NotImplementedException(\n\t\t\t\"visitQuantifiedSentence() should not be called.\");\n\t    }\n\t    // END-FOLVisitor    \n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/Demodulation.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing aima.core.logic.fol.inference.proof;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 354.<br>\n     * <br>\n     * Demodulation: For any terms x, y, and z, where z appears somewhere in literal\n     * m<sub>i</sub> and where UNIFY(x,z) = &theta;:<br>\n     * \n     * <pre>\n     *                 x=y,    m<sub>1</sub> OR ... OR m<sub>n</sub>[z]\n     *     ------------------------------------------------------------\n     *     SUB(SUBST(&theta;,x), SUBST(&theta;,y), m<sub>1</sub> OR ... OR m<sub>n</sub>)\n     * </pre>\n     * \n     * where SUBST is the usual substitution of a binding list, and SUB(x,y,m) means\n     * to replace x with y everywhere that x occurs within m.<br>\n     * <br>\n     * Some additional restrictions/clarifications highlighted in:<br>\n     * <a href=\"http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf\"\n     * >Demodulation Restrictions</a> <br>\n     * 1. Unit Equations Only.<br>\n     * 2. Variables substituted in Equation Only.<br>\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class Demodulation : AbstractModulation\n    {\n\tpublic Demodulation()\n\t{\n\n\t}\n\n\tpublic Clause apply(TermEquality assertion, Clause clExpression)\n\t{\n\t    Clause altClExpression = null;\n\n\t    foreach (Literal l1 in clExpression.getLiterals())\n\t    {\n\t\tAtomicSentence altExpression = apply(assertion, l1\n\t\t\t.getAtomicSentence());\n\t\tif (null != altExpression)\n\t\t{\n\t\t    // I have an alternative, create a new clause\n\t\t    // with the alternative and return\n\t\t    List<Literal> newLits = new List<Literal>();\n\t\t    foreach (Literal l2 in clExpression.getLiterals())\n\t\t    {\n\t\t\tif (l1.Equals(l2))\n\t\t\t{\n\t\t\t    newLits.Add(l1.newInstance(altExpression));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t    newLits.Add(l2);\n\t\t\t}\n\t\t    }\n\t\t    // Only apply demodulation at most once on\n\t\t    // each call.\n\t\t    altClExpression = new Clause(newLits);\n\t\t    altClExpression.setProofStep(new ProofStepClauseDemodulation(\n\t\t\t    altClExpression, clExpression, assertion));\n\t\t    if (clExpression.isImmutable())\n\t\t    {\n\t\t\taltClExpression.setImmutable();\n\t\t    }\n\t\t    if (!clExpression.isStandardizedApartCheckRequired())\n\t\t    {\n\t\t\taltClExpression.setStandardizedApartCheckNotRequired();\n\t\t    }\n\t\t    break;\n\t\t}\n\t    }\n\n\t    return altClExpression;\n\t}\n\n\tpublic AtomicSentence apply(TermEquality assertion,\n\t\tAtomicSentence expression)\n\t{\n\t    AtomicSentence altExpression = null;\n\n\t    IdentifyCandidateMatchingTerm icm = getMatchingSubstitution(assertion\n\t\t    .getTerm1(), expression);\n\n\t    if (null != icm)\n\t    {\n\t\tTerm replaceWith = substVisitor.subst(\n\t\t\ticm.getMatchingSubstitution(), assertion.getTerm2());\n\t\t// Want to ignore reflexivity axiom situation, i.e. x = x\n\t\tif (!icm.getMatchingTerm().Equals(replaceWith))\n\t\t{\n\t\t    ReplaceMatchingTerm rmt = new ReplaceMatchingTerm();\n\n\t\t    // Only apply demodulation at most once on each call.\n\t\t    altExpression = rmt.replace(expression, icm.getMatchingTerm(),\n\t\t\t    replaceWith);\n\t\t}\n\t    }\n\t    return altExpression;\n\t}\n\n\t// PROTECTED METHODS\t\n\tpublic override bool isValidMatch(Term toMatch,\n\t\tList<Variable> toMatchVariables, Term possibleMatch,\n\t\tDictionary<Variable, Term> substitution)\n\t{\n\t    // Demodulation only allows substitution in the equation only,\n\t    // if the substitution contains variables not in the toMatch\n\t    // side of the equation (i.e. left hand side), then\n\t    // it is not a legal demodulation match.\n\t    // Note: see:\n\t    // http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf\n\t    // slide 23 for an example.\n\t    bool contained = !substitution.Keys.Except(toMatchVariables).Any();\n\t    if (contained)\n\t    {\n\t\treturn true;\n\t    }\n\t    return false;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/FOLBCAsk.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing aima.core.logic.fol.inference.proof;\nusing aima.core.logic.fol.kb;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * Artificial Intelligence A Modern Approach (2nd Edition): Figure 9.6, page\n     * 288.<br>\n     * <br>\n     * \n     * <pre>\n     * function FOL-BC-ASK(KB, goals, theta) returns a set of substitutions\n     *   input: KB, a knowledge base\n     *          goals, a list of conjuncts forming a query (theta already applied)\n     *          theta, the current substitution, initially the empty substitution {}\n     *   local variables: answers, a set of substitutions, initially empty\n     *   \n     *   if goals is empty then return {theta}\n     *   qDelta &lt;- SUBST(theta, FIRST(goals))\n     *   for each sentence r in KB where STANDARDIZE-APART(r) = (p1 &circ; ... &circ; pn =&gt; q)\n     *          and thetaDelta &lt;- UNIFY(q, qDelta) succeeds\n     *       new_goals &lt;- [p1,...,pn|REST(goals)]\n     *       answers &lt;- FOL-BC-ASK(KB, new_goals, COMPOSE(thetaDelta, theta)) U answers\n     *   return answers\n     * </pre>\n     * \n     * Figure 9.6 A simple backward-chaining algorithm.\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n    public class FOLBCAsk : InferenceProcedure\n    {\n\tpublic FOLBCAsk()\n\t{\n\n\t}\n\n\t// START-InferenceProcedure\n\t/**\n\t * Returns a set of substitutions\n\t * \n\t * @param KB\n\t *            a knowledge base\n\t * @param query\n\t *            goals, a list of conjuncts forming a query\n\t * \n\t * @return a set of substitutions\n\t */\n\tpublic InferenceResult ask(FOLKnowledgeBase KB, Sentence query)\n\t{\n\t    // Assertions on the type queries this Inference procedure\n\t    // supports\n\t    if (!(query is AtomicSentence))\n\t    {\n\t\tthrow new ArgumentException(\n\t\t\t\"Only Atomic Queries are supported.\");\n\t    }\n\n\t    List<Literal> goals = new List<Literal>();\n\t    goals.Add(new Literal((AtomicSentence)query));\n\n\t    BCAskAnswerHandler ansHandler = new BCAskAnswerHandler();\n\n\t    List<List<ProofStepBwChGoal>> allProofSteps = folbcask(KB, ansHandler,\n\t\t    goals, new Dictionary<Variable, Term>());\n\n\t    ansHandler.setAllProofSteps(allProofSteps);\n\n\t    return ansHandler;\n\t}\n\t// END-InferenceProcedure\n\n\t// PRIVATE METHODS\n\t\n\t/**\n         * <code>\n         * function FOL-BC-ASK(KB, goals, theta) returns a set of substitutions\n         *   input: KB, a knowledge base\n         *          goals, a list of conjuncts forming a query (theta already applied)\n         *          theta, the current substitution, initially the empty substitution {}\n         * </code>\n         */\n\tprivate List<List<ProofStepBwChGoal>> folbcask(FOLKnowledgeBase KB,\n\t\tBCAskAnswerHandler ansHandler, List<Literal> goals,\n\t\tDictionary<Variable, Term> theta)\n\t{\n\t    List<List<ProofStepBwChGoal>> thisLevelProofSteps = new List<List<ProofStepBwChGoal>>();\n\t    // local variables: answers, a set of substitutions, initially empty\n\n\t    // if goals is empty then return {theta}\n\t    if (goals.Count == 0)\n\t    {\n\t\tthisLevelProofSteps.Add(new List<ProofStepBwChGoal>());\n\t\treturn thisLevelProofSteps;\n\t    }\n\n\t    // qDelta <- SUBST(theta, FIRST(goals))\n\t    Literal qDelta = KB.subst(theta, goals[0]);\n\n\t    // for each sentence r in KB where\n\t    // STANDARDIZE-APART(r) = (p1 ^ ... ^ pn => q)\n\t    foreach (Clause r in KB.getAllDefiniteClauses())\n\t    {\n\t\tClause r2 = KB.standardizeApart(r);\n\t\t// and thetaDelta <- UNIFY(q, qDelta) succeeds\n\t\tDictionary<Variable, Term> thetaDelta = KB.unify(r2.getPositiveLiterals()\n\t\t\t[0].getAtomicSentence(), qDelta.getAtomicSentence());\n\t\tif (null != thetaDelta)\n\t\t{\n\t\t    // new_goals <- [p1,...,pn|REST(goals)]\n\t\t    List<Literal> newGoals = new List<Literal>(r2\n\t\t\t    .getNegativeLiterals());\n\t\t    newGoals.AddRange(goals.Skip(1));\n\t\t    // answers <- FOL-BC-ASK(KB, new_goals, COMPOSE(thetaDelta,\n\t\t    // theta)) U answers\n\t\t    Dictionary<Variable, Term> composed = compose(KB, thetaDelta, theta);\n\t\t    List<List<ProofStepBwChGoal>> lowerLevelProofSteps = folbcask(\n\t\t\t    KB, ansHandler, newGoals, composed);\n\n\t\t    ansHandler.addProofStep(lowerLevelProofSteps, r2, qDelta,\n\t\t\t    composed);\n\n\t\t    thisLevelProofSteps.AddRange(lowerLevelProofSteps);\n\t\t}\n\t    }\n\t    // return answers\n\t    return thisLevelProofSteps;\n\t}\n\n\t// Artificial Intelligence A Modern Approach (2nd Edition): page 288.\n\t// COMPOSE(delta, tau) is the substitution whose effect is identical to\n\t// the effect of applying each substitution in turn. That is,\n\t// SUBST(COMPOSE(theta1, theta2), p) = SUBST(theta2, SUBST(theta1, p))\n\tprivate Dictionary<Variable, Term> compose(FOLKnowledgeBase KB,\n\t\tDictionary<Variable, Term> theta1, Dictionary<Variable, Term> theta2)\n\t{\n\t    Dictionary<Variable, Term> composed = new Dictionary<Variable, Term>();\n\n\t    // So that it behaves like:\n\t    // SUBST(theta2, SUBST(theta1, p))\n\t    // There are two steps involved here.\n\t    // See: http://logic.stanford.edu/classes/cs157/2008/notes/chap09.pdf\n\t    // for a detailed discussion:\n\n\t    // 1. Apply theta2 to the range of theta1.\n\t    foreach (Variable v in theta1.Keys)\n\t    {\n\t\tcomposed.Add(v, KB.subst(theta2, theta1[v]));\n\t    }\n\n\t    // 2. Adjoin to delta all pairs from tau with different\n\t    // domain variables.\n\t    foreach (Variable v in theta2.Keys)\n\t    {\n\t\tif (!theta1.ContainsKey(v))\n\t\t{\n\t\t    composed.Add(v, theta2[v]);\n\t\t}\n\t    }\n\n\t    return cascadeSubstitutions(KB, composed);\n\t}\n\n\t// See:\n\t// http://logic.stanford.edu/classes/cs157/2008/miscellaneous/faq.html#jump165\n\t// for need for this.\n\tprivate Dictionary<Variable, Term> cascadeSubstitutions(FOLKnowledgeBase KB,\n\t\tDictionary<Variable, Term> theta)\n\t{\n\t    foreach (Variable v in theta.Keys)\n\t    {\n\t\tTerm t = theta[v];\n\t\ttheta.Add(v, KB.subst(theta, t));\n\t    }\n\n\t    return theta;\n\t}\n\n\tclass BCAskAnswerHandler : InferenceResult\n\t{\n\n\t    private List<Proof> proofs = new List<Proof>();\n\n\t    public BCAskAnswerHandler()\n\t    {\n\n\t    }\n\t    \t    \n\t    // START-InferenceResult\n\t    public bool isPossiblyFalse()\n\t    {\n\t\treturn proofs.Count == 0;\n\t    }\n\n\t    public bool isTrue()\n\t    {\n\t\treturn proofs.Count > 0;\n\t    }\n\n\t    public bool isUnknownDueToTimeout()\n\t    {\n\t\treturn false;\n\t    }\n\n\t    public bool isPartialResultDueToTimeout()\n\t    {\n\t\treturn false;\n\t    }\n\n\t    public List<Proof> getProofs()\n\t    {\n\t\treturn proofs;\n\t    }\n\t    // END-InferenceResult\n\t    \n\t    public void setAllProofSteps(List<List<ProofStepBwChGoal>> allProofSteps)\n\t    {\n\t\tforeach (List<ProofStepBwChGoal> steps in allProofSteps)\n\t\t{\n\t\t    ProofStepBwChGoal lastStep = steps[steps.Count - 1];\n\t\t    Dictionary<Variable, Term> theta = lastStep.getBindings();\n\t\t    proofs.Add(new ProofFinal(lastStep, theta));\n\t\t}\n\t    }\n\n\t    public void addProofStep(\n\t\t    List<List<ProofStepBwChGoal>> currentLevelProofSteps,\n\t\t    Clause toProve, Literal currentGoal,\n\t\t    Dictionary<Variable, Term> bindings)\n\t    {\n\n\t\tif (currentLevelProofSteps.Count > 0)\n\t\t{\n\t\t    ProofStepBwChGoal predecessor = new ProofStepBwChGoal(toProve,\n\t\t\t    currentGoal, bindings);\n\t\t    foreach (List<ProofStepBwChGoal> steps in currentLevelProofSteps)\n\t\t    {\n\t\t\tif (steps.Count > 0)\n\t\t\t{\n\t\t\t    steps[0].setPredecessor(predecessor);\n\t\t\t}\n\t\t\tsteps.Insert(0, predecessor);\n\t\t    }\n\t\t}\n\t    }\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/FOLFCAsk.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.inference.proof;\nusing aima.core.logic.fol.kb;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 9.3, page 332.\n     * \n     * <pre>\n     * function FOL-FC-ASK(KB, alpha) returns a substitution or false\n     *   inputs: KB, the knowledge base, a set of first order definite clauses\n     *           alpha, the query, an atomic sentence\n     *   local variables: new, the new sentences inferred on each iteration\n     *   \n     *   repeat until new is empty\n     *      new <- {}\n     *      for each rule in KB do\n     *          (p1 ^ ... ^ pn => q) <- STANDARDIZE-VARAIBLES(rule)\n     *          for each theta such that SUBST(theta, p1 ^ ... ^ pn) = SUBST(theta, p'1 ^ ... ^ p'n)\n     *                         for some p'1,...,p'n in KB\n     *              q' <- SUBST(theta, q)\n     *              if q' does not unify with some sentence already in KB or new then\n     *                   add q' to new\n     *                   theta <- UNIFY(q', alpha)\n     *                   if theta is not fail then return theta\n     *      add new to KB\n     *   return false\n     * </pre>\n     * \n     * Figure 9.3 A conceptually straightforward, but very inefficient forward-chaining algo-\n     * rithm. On each iteration, it adds to KB all the atomic sentences that can be inferred in one\n     * step from the implication sentences and the atomic sentences already in KB. The function\n     * STANDARDIZE-VARIABLES replaces all variables in its arguments with new ones that have\n     * not been used before.\n     */\n\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class FOLFCAsk : InferenceProcedure\n    {\n\tpublic FOLFCAsk()\n\t{\n\n\t}\n\t\n\t// START-InferenceProcedure\n\n\t/**\n         * <code>\n         * function FOL-FC-ASK(KB, alpha) returns a substitution or false\n         *   inputs: KB, the knowledge base, a set of first order definite clauses\n         *           alpha, the query, an atomic sentence\n         * </code>\n         */\n\tpublic InferenceResult ask(FOLKnowledgeBase KB, Sentence query)\n\t{\n\t    // Assertions on the type of queries this Inference procedure\n\t    // supports\n\t    if (!(query is AtomicSentence))\n\t    {\n\t\tthrow new ArgumentException(\n\t\t\t\"Only Atomic Queries are supported.\");\n\t    }\n\n\t    FCAskAnswerHandler ansHandler = new FCAskAnswerHandler();\n\n\t    Literal alpha = new Literal((AtomicSentence)query);\n\n\t    // local variables: new, the new sentences inferred on each iteration\n\t    List<Literal> newSentences = new List<Literal>();\n\n\t    // Ensure query is not already a know fact before\n\t    // attempting forward chaining.\n\t    List<Dictionary<Variable, Term>> answers = KB.fetch(alpha);\n\t    if (answers.Count > 0)\n\t    {\n\t\tansHandler.addProofStep(new ProofStepFoChAlreadyAFact(alpha));\n\t\tansHandler.setAnswers(answers);\n\t\treturn ansHandler;\n\t    }\n\n\t    // repeat until new is empty\n\t    do\n\t    {\n\t\t// new <- {}\n\t\tnewSentences.Clear();\n\t\t// for each rule in KB do\n\t\t// (p1 ^ ... ^ pn => q) <-STANDARDIZE-VARIABLES(rule)\n\t\tforeach (Clause impl in KB.getAllDefiniteClauseImplications())\n\t\t{\n\t\t    Clause impl2 = KB.standardizeApart(impl);\n\t\t    // for each theta such that SUBST(theta, p1 ^ ... ^ pn) =\n\t\t    // SUBST(theta, p'1 ^ ... ^ p'n)\n\t\t    // --- for some p'1,...,p'n in KB\n\t\t    foreach (Dictionary<Variable, Term> theta in KB.fetch(invert(new List<Literal>(impl2\n\t\t\t    .getNegativeLiterals()))))\n\t\t    {\n\t\t\t// q' <- SUBST(theta, q)\n\t\t\tLiteral qPrime = KB.subst(theta, impl.getPositiveLiterals()\n\t\t\t\t[0]);\n\t\t\t// if q' does not unify with some sentence already in KB or\n\t\t\t// new then do\n\t\t\tif (!KB.isRenaming(qPrime)\n\t\t\t\t&& !KB.isRenaming(qPrime, newSentences))\n\t\t\t{\n\t\t\t    // add q' to new\n\t\t\t    newSentences.Add(qPrime);\n\t\t\t    ansHandler.addProofStep(impl, qPrime, theta);\n\t\t\t    // theta <- UNIFY(q', alpha)\n\t\t\t    Dictionary<Variable, Term> theta2 = KB.unify(qPrime.getAtomicSentence(), alpha\n\t\t\t\t    .getAtomicSentence());\n\t\t\t    // if theta is not fail then return theta\n\t\t\t    if (null != theta2)\n\t\t\t    {\n\t\t\t\tforeach (Literal l in newSentences)\n\t\t\t\t{\n\t\t\t\t    Sentence s = null;\n\t\t\t\t    if (l.isPositiveLiteral())\n\t\t\t\t    {\n\t\t\t\t\ts = l.getAtomicSentence();\n\t\t\t\t    }\n\t\t\t\t    else\n\t\t\t\t    {\n\t\t\t\t\ts = new NotSentence(l.getAtomicSentence());\n\t\t\t\t    }\n\t\t\t\t    KB.tell(s);\n\t\t\t\t}\n\t\t\t\tansHandler.setAnswers(KB.fetch(alpha));\n\t\t\t\treturn ansHandler;\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t\t// add new to KB\n\t\tforeach (Literal l in newSentences)\n\t\t{\n\t\t    Sentence s = null;\n\t\t    if (l.isPositiveLiteral())\n\t\t    {\n\t\t\ts = l.getAtomicSentence();\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\ts = new NotSentence(l.getAtomicSentence());\n\t\t    }\n\t\t    KB.tell(s);\n\t\t}\n\t    } while (newSentences.Count > 0);\n\t    // return false\n\t    return ansHandler;\n\t}\n\t// END-InferenceProcedure\t\n\t\n\t// PRIVATE METHODS\t\n\tprivate List<Literal> invert(List<Literal> lits)\n\t{\n\t    List<Literal> invLits = new List<Literal>();\n\t    foreach (Literal l in lits)\n\t    {\n\t\tinvLits.Add(new Literal(l.getAtomicSentence(), (l\n\t\t\t.isPositiveLiteral() ? true : false)));\n\t    }\n\t    return invLits;\n\t}\n\n\tclass FCAskAnswerHandler : InferenceResult\n\t{\n\n\t    private ProofStep stepFinal = null;\n\t    private List<Proof> proofs = new List<Proof>();\n\n\t    public FCAskAnswerHandler()\n\t    {\n\n\t    }\n\t    \t    \n\t    // START-InferenceResult\n\t    public bool isPossiblyFalse()\n\t    {\n\t\treturn proofs.Count == 0;\n\t    }\n\n\t    public bool isTrue()\n\t    {\n\t\treturn proofs.Count > 0;\n\t    }\n\n\t    public bool isUnknownDueToTimeout()\n\t    {\n\t\treturn false;\n\t    }\n\n\t    public bool isPartialResultDueToTimeout()\n\t    {\n\t\treturn false;\n\t    }\n\n\t    public List<Proof> getProofs()\n\t    {\n\t\treturn proofs;\n\t    }\n\t    // END-InferenceResult\n\t    \n\t    public void addProofStep(Clause implication, Literal fact,\n\t\t    Dictionary<Variable, Term> bindings)\n\t    {\n\t\tstepFinal = new ProofStepFoChAssertFact(implication, fact,\n\t\t\tbindings, stepFinal);\n\t    }\n\n\t    public void addProofStep(ProofStep step)\n\t    {\n\t\tstepFinal = step;\n\t    }\n\n\t    public void setAnswers(List<Dictionary<Variable, Term>> answers)\n\t    {\n\t\tforeach (Dictionary<Variable, Term> ans in answers)\n\t\t{\n\t\t    proofs.Add(new ProofFinal(stepFinal, ans));\n\t\t}\n\t    }\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/FOLModelElimination.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing aima.core.logic.fol.kb;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\nusing aima.core.logic.fol.inference.proof;\nusing aima.core.logic.fol.inference.trace;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * Based on lecture notes from:<br>\n     * <a\n     * href=\"http://logic.stanford.edu/classes/cs157/2008/lectures/lecture13.pdf\">\n     * http://logic.stanford.edu/classes/cs157/2008/lectures/lecture13.pdf</a>\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class FOLModelElimination : InferenceProcedure\n    {\n\t// Ten seconds is default maximum query time permitted\n\tprivate long maxQueryTime = 10 * 1000;\t\n\tprivate FOLModelEliminationTracer tracer = null;\t\n\tprivate Unifier unifier = new Unifier();\n\tprivate SubstVisitor substVisitor = new SubstVisitor();\n\n\tpublic FOLModelElimination()\n\t{\n\n\t}\n\n\tpublic FOLModelElimination(long maxQueryTime)\n\t{\n\t    setMaxQueryTime(maxQueryTime);\n\t}\n\n\tpublic FOLModelElimination(FOLModelEliminationTracer tracer)\n\t{\n\t    this.tracer = tracer;\n\t}\n\n\tpublic FOLModelElimination(FOLModelEliminationTracer tracer,\n\t\tlong maxQueryTime)\n\t{\n\t    this.tracer = tracer;\n\t    setMaxQueryTime(maxQueryTime);\n\t}\n\n\tpublic long getMaxQueryTime()\n\t{\n\t    return maxQueryTime;\n\t}\n\n\tpublic void setMaxQueryTime(long maxQueryTime)\n\t{\n\t    this.maxQueryTime = maxQueryTime;\n\t}\n\n\t// START-InferenceProcedure\n\n\tpublic InferenceResult ask(FOLKnowledgeBase kb, Sentence aQuery)\n\t{\n\t    // Get the background knowledge - are assuming this is satisfiable\n\t    // as using Set of Support strategy.\n\t    List<Clause> bgClauses = new List<Clause>(kb.getAllClauses());\n\t    List<Clause> removeList = SubsumptionElimination.findSubsumedClauses(bgClauses);\n\t    foreach (Clause c in removeList)\n\t    {\n\t\tbgClauses.Remove(c);\n\t    }\n\t    List<Chain> background = createChainsFromClauses(bgClauses);\n\n\t    // Collect the information necessary for constructing\n\t    // an answer (supports use of answer literals).\n\t    AnswerHandler ansHandler = new AnswerHandler(kb, aQuery, maxQueryTime, this);\n\n\t    IndexedFarParents ifps = new IndexedFarParents(ansHandler\n\t\t    .getSetOfSupport(), background);\n\n\t    // Iterative deepening to be used\n\t    for (int maxDepth = 1; maxDepth < int.MaxValue; maxDepth++)\n\t    {\n\t\t// Track the depth actually reached\n\t\tansHandler.resetMaxDepthReached();\n\n\t\tif (null != tracer)\n\t\t{\n\t\t    tracer.reset();\n\t\t}\n\n\t\tforeach (Chain nearParent in ansHandler.getSetOfSupport())\n\t\t{\n\t\t    recursiveDLS(maxDepth, 0, nearParent, ifps, ansHandler);\n\t\t    if (ansHandler.isComplete())\n\t\t    {\n\t\t\treturn ansHandler;\n\t\t    }\n\t\t}\n\t\t// This means the search tree\n\t\t// has bottomed out (i.e. finite).\n\t\t// Return what I know based on exploring everything.\n\t\tif (ansHandler.getMaxDepthReached() < maxDepth)\n\t\t{\n\t\t    return ansHandler;\n\t\t}\n\t    }\n\n\t    return ansHandler;\n\t}\n\n\t// END-InferenceProcedure\n\t\n\t// PRIVATE METHODS\n\t\n\tpublic List<Chain> createChainsFromClauses(List<Clause> clauses)\n\t{\n\t    List<Chain> chains = new List<Chain>();\n\n\t    foreach (Clause c in clauses)\n\t    {\n\t\tChain chn = new Chain(c.getLiterals());\n\t\tchn.setProofStep(new ProofStepChainFromClause(chn, c));\n\t\tchains.Add(chn);\n\t\tchains.AddRange(chn.getContrapositives());\n\t    }\n\n\t    return chains;\n\t}\n\n\t// Recursive Depth Limited Search\n\tprivate void recursiveDLS(int maxDepth, int currentDepth, Chain nearParent,\n\t\tIndexedFarParents indexedFarParents, AnswerHandler ansHandler)\n\t{\n\n\t    // Keep track of the maximum depth reached.\n\t    ansHandler.updateMaxDepthReached(currentDepth);\n\n\t    if (currentDepth == maxDepth)\n\t    {\n\t\treturn;\n\t    }\n\n\t    int noCandidateFarParents = indexedFarParents\n\t\t    .getNumberCandidateFarParents(nearParent);\n\t    if (null != tracer)\n\t    {\n\t\ttracer.increment(currentDepth, noCandidateFarParents);\n\t    }\n\t    indexedFarParents.standardizeApart(nearParent);\n\t    for (int farParentIdx = 0; farParentIdx < noCandidateFarParents; farParentIdx++)\n\t    {\n\t\t// If have a complete answer, don't keep\n\t\t// checking candidate far parents\n\t\tif (ansHandler.isComplete())\n\t\t{\n\t\t    break;\n\t\t}\n\n\t\t// Reduction\n\t\tChain nextNearParent = indexedFarParents.attemptReduction(\n\t\t\tnearParent, farParentIdx);\n\n\t\tif (null == nextNearParent)\n\t\t{\n\t\t    // Unable to remove the head via reduction\n\t\t    continue;\n\t\t}\n\n\t\t// Handle Canceling and Dropping\n\t\tbool cancelled = false;\n\t\tbool dropped = false;\n\t\tdo\n\t\t{\n\t\t    cancelled = false;\n\t\t    Chain nextParent = null;\n\t\t    while (nextNearParent != (nextParent = tryCancellation(nextNearParent)))\n\t\t    {\n\t\t\tnextNearParent = nextParent;\n\t\t\tcancelled = true;\n\t\t    }\n\n\t\t    dropped = false;\n\t\t    while (nextNearParent != (nextParent = tryDropping(nextNearParent)))\n\t\t    {\n\t\t\tnextNearParent = nextParent;\n\t\t\tdropped = true;\n\t\t    }\n\t\t} while (dropped || cancelled);\n\n\t\t// Check if have answer before\n\t\t// going to the next level\n\t\tif (!ansHandler.isAnswer(nextNearParent))\n\t\t{\n\t\t    // Keep track of the current # of\n\t\t    // far parents that are possible for the next near parent.\n\t\t    int noNextFarParents = indexedFarParents\n\t\t\t    .getNumberFarParents(nextNearParent);\n\t\t    // Add to indexed far parents\n\t\t    nextNearParent = indexedFarParents.addToIndex(nextNearParent);\n\n\t\t    // Check the next level\n\t\t    recursiveDLS(maxDepth, currentDepth + 1, nextNearParent,\n\t\t\t    indexedFarParents, ansHandler);\n\n\t\t    // Reset the number of far parents possible\n\t\t    // when recursing back up.\n\t\t    indexedFarParents.resetNumberFarParentsTo(nextNearParent,\n\t\t\t    noNextFarParents);\n\t\t}\n\t    }\n\t}\n\n\t// Returns c if no cancellation occurred\n\tprivate Chain tryCancellation(Chain c)\n\t{\n\t    Literal head = c.getHead();\n\t    if (null != head && !(head is ReducedLiteral))\n\t    {\n\t\tforeach (Literal l in c.getTail())\n\t\t{\n\t\t    if (l is ReducedLiteral)\n\t\t    {\n\t\t\t// if they can be resolved\n\t\t\tif (head.isNegativeLiteral() != l.isNegativeLiteral())\n\t\t\t{\n\t\t\t    Dictionary<Variable, Term> subst = unifier.unify(head\n\t\t\t\t    .getAtomicSentence(), l.getAtomicSentence());\n\t\t\t    if (null != subst)\n\t\t\t    {\n\t\t\t\t// I have a cancellation\n\t\t\t\t// Need to apply subst to all of the\n\t\t\t\t// literals in the cancellation\n\t\t\t\tList<Literal> cancLits = new List<Literal>();\n\t\t\t\tforeach (Literal lfc in c.getTail())\n\t\t\t\t{\n\t\t\t\t    AtomicSentence a = (AtomicSentence)substVisitor\n\t\t\t\t\t    .subst(subst, lfc.getAtomicSentence());\n\t\t\t\t    cancLits.Add(lfc.newInstance(a));\n\t\t\t\t}\n\t\t\t\tChain cancellation = new Chain(cancLits);\n\t\t\t\tcancellation\n\t\t\t\t\t.setProofStep(new ProofStepChainCancellation(\n\t\t\t\t\t\tcancellation, c, subst));\n\t\t\t\treturn cancellation;\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t    return c;\n\t}\n\n\t// Returns c if no dropping occurred\n\tprivate Chain tryDropping(Chain c)\n\t{\n\t    Literal head = c.getHead();\n\t    if (null != head && (head is ReducedLiteral))\n\t    {\n\t\tChain dropped = new Chain(c.getTail());\n\t\tdropped.setProofStep(new ProofStepChainDropped(dropped, c));\n\t\treturn dropped;\n\t    }\n\n\t    return c;\n\t}\n\n\tclass AnswerHandler : InferenceResult\n\t{\n\t    private Chain answerChain = new Chain();\n\t    private List<Variable> answerLiteralVariables;\n\t    private List<Chain> sos = null;\n\t    private bool complete = false;\n\t    private long finishTime = 0L;\n\t    private int maxDepthReached = 0;\n\t    private List<Proof> proofs = new List<Proof>();\n\t    private bool timedOut = false;\n\n\t    public AnswerHandler(FOLKnowledgeBase kb, Sentence aQuery,\n\t\t    long maxQueryTime, FOLModelElimination folModelElimination)\n\t    {\n\n\t\tfinishTime = System.DateTime.UtcNow.Ticks + maxQueryTime;\n\n\t\tSentence refutationQuery = new NotSentence(aQuery);\n\n\t\t// Want to use an answer literal to pull\n\t\t// query variables where necessary\n\t\tLiteral answerLiteral = kb.createAnswerLiteral(refutationQuery);\n\t\tanswerLiteralVariables = kb.collectAllVariables(answerLiteral\n\t\t\t.getAtomicSentence());\n\n\t\t// Create the Set of Support based on the Query.\n\t\tif (answerLiteralVariables.Count > 0)\n\t\t{\n\t\t    Sentence refutationQueryWithAnswer = new ConnectedSentence(\n\t\t\t    Connectors.OR, refutationQuery, (Sentence)answerLiteral\n\t\t\t\t    .getAtomicSentence().copy());\n\n\t\t    sos = folModelElimination.createChainsFromClauses(kb\n\t\t\t    .convertToClauses(refutationQueryWithAnswer));\n\n\t\t    answerChain.addLiteral(answerLiteral);\n\t\t}\n\t\telse\n\t\t{\n\t\t    sos = folModelElimination.createChainsFromClauses(kb\n\t\t\t    .convertToClauses(refutationQuery));\n\t\t}\n\n\t\tforeach (Chain s in sos)\n\t\t{\n\t\t    s.setProofStep(new ProofStepGoal(s));\n\t\t}\n\t    }\n\n\t    // START-InferenceResult\n\t    public bool isPossiblyFalse()\n\t    {\n\t\treturn !timedOut && proofs.Count == 0;\n\t    }\n\n\t    public bool isTrue()\n\t    {\n\t\treturn proofs.Count > 0;\n\t    }\n\n\t    public bool isUnknownDueToTimeout()\n\t    {\n\t\treturn timedOut && proofs.Count == 0;\n\t    }\n\n\t    public bool isPartialResultDueToTimeout()\n\t    {\n\t\treturn timedOut && proofs.Count > 0;\n\t    }\n\n\t    public List<Proof> getProofs()\n\t    {\n\t\treturn proofs;\n\t    }\n\n\t    // END-InferenceResult\n\t    \n\t    public List<Chain> getSetOfSupport()\n\t    {\n\t\treturn sos;\n\t    }\n\n\t    public bool isComplete()\n\t    {\n\t\treturn complete;\n\t    }\n\n\t    public void resetMaxDepthReached()\n\t    {\n\t\tmaxDepthReached = 0;\n\t    }\n\n\t    public int getMaxDepthReached()\n\t    {\n\t\treturn maxDepthReached;\n\t    }\n\n\t    public void updateMaxDepthReached(int depth)\n\t    {\n\t\tif (depth > maxDepthReached)\n\t\t{\n\t\t    maxDepthReached = depth;\n\t\t}\n\t    }\n\n\t    public bool isAnswer(Chain nearParent)\n\t    {\n\t\tbool isAns = false;\n\t\tif (answerChain.isEmpty())\n\t\t{\n\t\t    if (nearParent.isEmpty())\n\t\t    {\n\t\t\tproofs.Add(new ProofFinal(nearParent.getProofStep(),\n\t\t\t\tnew Dictionary<Variable, Term>()));\n\t\t\tcomplete = true;\n\t\t\tisAns = true;\n\t\t    }\n\t\t}\n\t\telse\n\t\t{\n\t\t    if (nearParent.isEmpty())\n\t\t    {\n\t\t\t// This should not happen\n\t\t\t// as added an answer literal to sos, which\n\t\t\t// implies the database (i.e. premises) are\n\t\t\t// unsatisfiable to begin with.\n\t\t\tthrow new ApplicationException(\n\t\t\t\t\"Generated an empty chain while looking for an answer, implies original KB is unsatisfiable\");\n\t\t    }\n\t\t    if (1 == nearParent.getNumberLiterals()\n\t\t\t    && nearParent.getHead().getAtomicSentence()\n\t\t\t\t    .getSymbolicName().Equals(\n\t\t\t\t\t    answerChain.getHead()\n\t\t\t\t\t\t    .getAtomicSentence()\n\t\t\t\t\t\t    .getSymbolicName()))\n\t\t    {\n\t\t\tDictionary<Variable, Term> answerBindings = new Dictionary<Variable, Term>();\n\t\t\tList<Term> answerTerms = nearParent.getHead()\n\t\t\t\t.getAtomicSentence().getArgs();\n\t\t\tint idx = 0;\n\t\t\tforeach (Variable v in answerLiteralVariables)\n\t\t\t{\n\t\t\t    answerBindings.Add(v, (Term)answerTerms[idx]);\n\t\t\t    idx++;\n\t\t\t}\n\t\t\tbool addNewAnswer = true;\n\t\t\tforeach (Proof p in proofs)\n\t\t\t{\n\t\t\t    if (p.getAnswerBindings().Equals(answerBindings))\n\t\t\t    {\n\t\t\t\taddNewAnswer = false;\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t\tif (addNewAnswer)\n\t\t\t{\n\t\t\t    proofs.Add(new ProofFinal(nearParent.getProofStep(),\n\t\t\t\t    answerBindings));\n\t\t\t}\n\t\t\tisAns = true;\n\t\t    }\n\t\t}\n\n\t\tif (DateTime.Now.Ticks > finishTime)\n\t\t{\n\t\t    complete = true;\n\t\t    // Indicate that I have run out of query time\n\t\t    timedOut = true;\n\t\t}\n\n\t\treturn isAns;\n\t    }\n\n\t    public override String ToString()\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(\"isComplete=\" + complete);\n\t\tsb.Append(\"\\n\");\n\t\tsb.Append(\"result=\" + proofs);\n\t\treturn sb.ToString();\n\t    }\n\t}\n    }\n\n    class IndexedFarParents\n    {\n\tprivate int saIdx = 0;\n\tprivate Unifier unifier = new Unifier();\n\tprivate SubstVisitor substVisitor = new SubstVisitor();\n\tprivate Dictionary<String, List<Chain>> posHeads = new Dictionary<String, List<Chain>>();\n\tprivate Dictionary<String, List<Chain>> negHeads = new Dictionary<String, List<Chain>>();\n\n\tpublic IndexedFarParents(List<Chain> sos, List<Chain> background)\n\t{\n\t    constructInternalDataStructures(sos, background);\n\t}\n\n\tpublic int getNumberFarParents(Chain farParent)\n\t{\n\t    Literal head = farParent.getHead();\n\n\t    Dictionary<String, List<Chain>> heads = null;\n\t    if (head.isPositiveLiteral())\n\t    {\n\t\theads = posHeads;\n\t    }\n\t    else\n\t    {\n\t\theads = negHeads;\n\t    }\n\t    String headKey = head.getAtomicSentence().getSymbolicName();\n\n\t    List<Chain> farParents = heads[headKey];\n\t    if (null != farParents)\n\t    {\n\t\treturn farParents.Count;\n\t    }\n\t    return 0;\n\t}\n\n\tpublic void resetNumberFarParentsTo(Chain farParent, int toSize)\n\t{\n\t    Literal head = farParent.getHead();\n\t    Dictionary<String, List<Chain>> heads = null;\n\t    if (head.isPositiveLiteral())\n\t    {\n\t\theads = posHeads;\n\t    }\n\t    else\n\t    {\n\t\theads = negHeads;\n\t    }\n\t    String key = head.getAtomicSentence().getSymbolicName();\n\t    List<Chain> farParents = heads[key];\n\t    while (farParents.Count > toSize)\n\t    {\n\t\tfarParents.RemoveAt(farParents.Count - 1);\n\t    }\n\t}\n\n\tpublic int getNumberCandidateFarParents(Chain nearParent)\n\t{\n\t    Literal nearestHead = nearParent.getHead();\n\n\t    Dictionary<String, List<Chain>> candidateHeads = null;\n\t    if (nearestHead.isPositiveLiteral())\n\t    {\n\t\tcandidateHeads = negHeads;\n\t    }\n\t    else\n\t    {\n\t\tcandidateHeads = posHeads;\n\t    }\n\n\t    String nearestKey = nearestHead.getAtomicSentence().getSymbolicName();\n\n\t    List<Chain> farParents = candidateHeads[nearestKey];\n\t    if (null != farParents)\n\t    {\n\t\treturn farParents.Count;\n\t    }\n\t    return 0;\n\t}\n\n\tpublic Chain attemptReduction(Chain nearParent, int farParentIndex)\n\t{\n\t    Chain nnpc = null;\n\n\t    Literal nearLiteral = nearParent.getHead();\n\n\t    Dictionary<String, List<Chain>> candidateHeads = null;\n\t    if (nearLiteral.isPositiveLiteral())\n\t    {\n\t\tcandidateHeads = negHeads;\n\t    }\n\t    else\n\t    {\n\t\tcandidateHeads = posHeads;\n\t    }\n\n\t    AtomicSentence nearAtom = nearLiteral.getAtomicSentence();\n\t    String nearestKey = nearAtom.getSymbolicName();\n\t    List<Chain> farParents = candidateHeads[nearestKey];\n\t    if (null != farParents)\n\t    {\n\t\tChain farParent = farParents[farParentIndex];\n\t\tstandardizeApart(farParent);\n\t\tLiteral farLiteral = farParent.getHead();\n\t\tAtomicSentence farAtom = farLiteral.getAtomicSentence();\n\t\tDictionary<Variable, Term> subst = unifier.unify(nearAtom, farAtom);\n\n\t\t// If I was able to unify with one\n\t\t// of the far heads\n\t\tif (null != subst)\n\t\t{\n\t\t    // Want to always apply reduction uniformly\n\t\t    Chain topChain = farParent;\n\t\t    Literal botLit = nearLiteral;\n\t\t    Chain botChain = nearParent;\n\n\t\t    // Need to apply subst to all of the\n\t\t    // literals in the reduction\n\t\t    List<Literal> reduction = new List<Literal>();\n\t\t    foreach (Literal l in topChain.getTail())\n\t\t    {\n\t\t\tAtomicSentence atom = (AtomicSentence)substVisitor.subst(\n\t\t\t\tsubst, l.getAtomicSentence());\n\t\t\treduction.Add(l.newInstance(atom));\n\t\t    }\n\t\t    reduction.Add(new ReducedLiteral((AtomicSentence)substVisitor\n\t\t\t    .subst(subst, botLit.getAtomicSentence()), botLit\n\t\t\t    .isNegativeLiteral()));\n\t\t    foreach (Literal l in botChain.getTail())\n\t\t    {\n\t\t\tAtomicSentence atom = (AtomicSentence)substVisitor.subst(\n\t\t\t\tsubst, l.getAtomicSentence());\n\t\t\treduction.Add(l.newInstance(atom));\n\t\t    }\n\n\t\t    nnpc = new Chain(reduction);\n\t\t    nnpc.setProofStep(new ProofStepChainReduction(nnpc, nearParent,\n\t\t\t    farParent, subst));\n\t\t}\n\t    }\n\t    return nnpc;\n\t}\n\n\tpublic Chain addToIndex(Chain c)\n\t{\n\t    Chain added = null;\n\t    Literal head = c.getHead();\n\t    if (null != head)\n\t    {\n\t\tDictionary<String, List<Chain>> toAddTo = null;\n\t\tif (head.isPositiveLiteral())\n\t\t{\n\t\t    toAddTo = posHeads;\n\t\t}\n\t\telse\n\t\t{\n\t\t    toAddTo = negHeads;\n\t\t}\n\n\t\tString key = head.getAtomicSentence().getSymbolicName();\n\t\tList<Chain> farParents = toAddTo[key];\n\t\tif (null == farParents)\n\t\t{\n\t\t    farParents = new List<Chain>();\n\t\t    toAddTo.Add(key, farParents);\n\t\t}\n\n\t\tadded = c;\n\t\tfarParents.Add(added);\n\t    }\n\t    return added;\n\t}\n\n\tpublic void standardizeApart(Chain c)\n\t{\n\t    saIdx = StandardizeApartInPlace.standardizeApart(c, saIdx);\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    StringBuilder sb = new StringBuilder();\n\n\t    sb.Append(\"#\");\n\t    sb.Append(posHeads.Count);\n\t    foreach (String key in posHeads.Keys)\n\t    {\n\t\tsb.Append(\",\");\n\t\tsb.Append(posHeads[key].Count);\n\t    }\n\t    sb.Append(\" posHeads=\");\n\t    sb.Append(posHeads.ToString());\n\t    sb.Append(\"\\n\");\n\t    sb.Append(\"#\");\n\t    sb.Append(negHeads.Count);\n\t    foreach (String key in negHeads.Keys)\n\t    {\n\t\tsb.Append(\",\");\n\t\tsb.Append(negHeads[key].Count);\n\t    }\n\t    sb.Append(\" negHeads=\");\n\t    sb.Append(negHeads.ToString());\n\n\t    return sb.ToString();\n\t}\n\n\t// PRIVATE METHODS\n\n\tprivate void constructInternalDataStructures(List<Chain> sos,\n\t\tList<Chain> background)\n\t{\n\t    List<Chain> toIndex = new List<Chain>();\n\t    toIndex.AddRange(sos);\n\t    toIndex.AddRange(background);\n\n\t    foreach (Chain c in toIndex)\n\t    {\n\t\taddToIndex(c);\n\t    }\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/FOLOTTERLikeTheoremProver.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing aima.core.logic.fol.inference.otter;\nusing aima.core.logic.fol.inference.otter.defaultimpl;\nusing aima.core.logic.fol.inference.proof;\nusing aima.core.logic.fol.kb;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\nusing aima.core.logic.fol;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n * Artificial Intelligence A Modern Approach (2nd Edition): Figure 9.14, page\n * 307.<br>\n * <br>\n * \n * <pre>\n * procedure OTTER(sos, usable)\n *   inputs: sos, a set of support-clauses defining the problem (a global variable)\n *   usable, background knowledge potentially relevant to the problem\n *   \n *   repeat\n *      clause <- the lightest member of sos\n *      move clause from sos to usable\n *      PROCESS(INFER(clause, usable), sos)\n *   until sos = [] or a refutation has been found\n * \n * --------------------------------------------------------------------------------\n * \n * function INFER(clause, usable) returns clauses\n *   \n *   resolve clause with each member of usable\n *   return the resulting clauses after applying filter\n *   \n * --------------------------------------------------------------------------------\n * \n * procedure PROCESS(clauses, sos)\n * \n *   for each clause in clauses do\n *       clause <- SIMPLIFY(clause)\n *       merge identical literals\n *       discard clause if it is a tautology\n *       sos <- [clause | sos]\n *       if clause has no literals then a refutation has been found\n *       if clause has one literal then look for unit refutation\n * </pre>\n * \n * Figure 9.14 Sketch of the OTTER theorem prover. Heuristic control is applied\n * in the selection of the \"lightest\" clause and in the FILTER function that\n * eliminates uninteresting clauses from consideration.<br>\n * <br>\n * <b>Note:</b> The original implementation of OTTER has been retired but its\n * successor, <b>Prover9</b>, can be found at:<br>\n * <a href=\"http://www.prover9.org/\">http://www.prover9.org/</a><br>\n * or<br>\n * <a href=\"http://www.cs.unm.edu/~mccune/mace4/\">http://www.cs.unm.edu/~mccune/\n * mace4/</a><br>\n * Should you wish to play with a mature implementation of a theorem prover :-)<br>\n * <br>\n * For lots of interesting problems to play with, see <b>The TPTP Problem\n * Library for Automated Theorem Proving</b>:<br>\n * <a href=\"http://www.cs.miami.edu/~tptp/\">http://www.cs.miami.edu/~tptp/</a><br>\n * \n * @author Ciaran O'Reilly\n * \n */\n    public class FOLOTTERLikeTheoremProver : InferenceProcedure\n    {\n\t// Ten seconds is default maximum query time permitted\n\tprivate long maxQueryTime = 10 * 1000;\n\tprivate bool useParamodulation = true;\n\tprivate LightestClauseHeuristic lightestClauseHeuristic = new DefaultLightestClauseHeuristic();\n\tprivate ClauseFilter clauseFilter = new DefaultClauseFilter();\n\tprivate ClauseSimplifier clauseSimplifier = new DefaultClauseSimplifier();\n\tprivate Paramodulation paramodulation = new Paramodulation();\n\n\tpublic FOLOTTERLikeTheoremProver()\n\t{\n\n\t}\n\n\tpublic FOLOTTERLikeTheoremProver(long maxQueryTime)\n\t{\n\t    setMaxQueryTime(maxQueryTime);\n\t}\n\n\tpublic FOLOTTERLikeTheoremProver(bool useParamodulation)\n\t{\n\t    setUseParamodulation(useParamodulation);\n\t}\n\n\tpublic FOLOTTERLikeTheoremProver(long maxQueryTime,\n\t\tbool useParamodulation)\n\t{\n\t    setMaxQueryTime(maxQueryTime);\n\t    setUseParamodulation(useParamodulation);\n\t}\n\n\tpublic long getMaxQueryTime()\n\t{\n\t    return maxQueryTime;\n\t}\n\n\tpublic void setMaxQueryTime(long maxQueryTime)\n\t{\n\t    this.maxQueryTime = maxQueryTime;\n\t}\n\n\tpublic bool isUseParamodulation()\n\t{\n\t    return useParamodulation;\n\t}\n\n\tpublic void setUseParamodulation(bool useParamodulation)\n\t{\n\t    this.useParamodulation = useParamodulation;\n\t}\n\n\tpublic LightestClauseHeuristic getLightestClauseHeuristic()\n\t{\n\t    return lightestClauseHeuristic;\n\t}\n\n\tpublic void setLightestClauseHeuristic(\n\t\tLightestClauseHeuristic lightestClauseHeuristic)\n\t{\n\t    this.lightestClauseHeuristic = lightestClauseHeuristic;\n\t}\n\n\tpublic ClauseFilter getClauseFilter()\n\t{\n\t    return clauseFilter;\n\t}\n\n\tpublic void setClauseFilter(ClauseFilter clauseFilter)\n\t{\n\t    this.clauseFilter = clauseFilter;\n\t}\n\n\tpublic ClauseSimplifier getClauseSimplifier()\n\t{\n\t    return clauseSimplifier;\n\t}\n\n\tpublic void setClauseSimplifier(ClauseSimplifier clauseSimplifier)\n\t{\n\t    this.clauseSimplifier = clauseSimplifier;\n\t}\n\n\t// START-InferenceProcedure\n\tpublic InferenceResult ask(FOLKnowledgeBase KB, Sentence alpha)\n\t{\n\t    List<Clause> sos = new List<Clause>();\n\t    List<Clause> usable = new List<Clause>();\n\n\t    // Usable set will be the set of clauses in the KB,\n\t    // are assuming this is satisfiable as using the\n\t    // Set of Support strategy.\n\t    foreach (Clause c in KB.getAllClauses())\n\t    {\n\t\tClause c2 = KB.standardizeApart(c);\n\t\tc2.setStandardizedApartCheckNotRequired();\n\t\tusable.AddRange(c2.getFactors());\n\t    }\n\n\t    // Ensure reflexivity axiom is added to usable if using paramodulation.\n\t    if (isUseParamodulation())\n\t    {\n\t\t// Reflexivity Axiom: x = x\n\t\tTermEquality reflexivityAxiom = new TermEquality(new Variable(\"x\"),\n\t\t\t\tnew Variable(\"x\"));\n\t\tClause reflexivityClause = new Clause();\n\t\treflexivityClause.addLiteral(new Literal(reflexivityAxiom));\n\t\treflexivityClause = KB.standardizeApart(reflexivityClause);\n\t\treflexivityClause.setStandardizedApartCheckNotRequired();\n\t\tusable.Add(reflexivityClause);\n\t    }\n\n\t    Sentence notAlpha = new NotSentence(alpha);\n\t    // Want to use an answer literal to pull\n\t    // query variables where necessary\n\t    Literal answerLiteral = KB.createAnswerLiteral(notAlpha);\n\t    List<Variable> answerLiteralVariables = KB\n\t\t\t    .collectAllVariables(answerLiteral.getAtomicSentence());\n\t    Clause answerClause = new Clause();\n\n\t    if (answerLiteralVariables.Count > 0)\n\t    {\n\t\tSentence notAlphaWithAnswer = new ConnectedSentence(Connectors.OR,\n\t\t\t\tnotAlpha, answerLiteral.getAtomicSentence());\n\t\tforeach (Clause c in KB.convertToClauses(notAlphaWithAnswer))\n\t\t{\n\t\t    Clause c2 = KB.standardizeApart(c);\n\t\t    c2.setProofStep(new ProofStepGoal(c2));\n\t\t    c2.setStandardizedApartCheckNotRequired();\n\t\t    sos.AddRange(c2.getFactors());\n\t\t}\n\n\t\tanswerClause.addLiteral(answerLiteral);\n\t    }\n\t    else\n\t    {\n\t\tforeach (Clause c in KB.convertToClauses(notAlpha))\n\t\t{\n\t\t    Clause c2 = KB.standardizeApart(c);\n\t\t    c2.setProofStep(new ProofStepGoal(c2));\n\t\t    c2.setStandardizedApartCheckNotRequired();\n\t\t    sos.AddRange(c2.getFactors());\n\t\t}\n\t    }\n\n\t    // Ensure all subsumed clauses are removed\n\t    foreach (Clause c in SubsumptionElimination.findSubsumedClauses(usable))\n\t    {\n\t\tusable.Remove(c);\n\t    }\n\t    foreach (Clause c in SubsumptionElimination.findSubsumedClauses(sos))\n\t    {\n\t\tsos.Remove(c);\n\t    }\n\n\t    OTTERAnswerHandler ansHandler = new OTTERAnswerHandler(answerLiteral,\n\t\t\t    answerLiteralVariables, answerClause, maxQueryTime);\n\n\t    IndexedClauses idxdClauses = new IndexedClauses(\n\t\t\t    getLightestClauseHeuristic(), sos, usable);\n\n\t    return otter(ansHandler, idxdClauses, sos, usable);\n\t}\n\n\t// END-InferenceProcedure\n\n\t/**\n         * <pre>\n         * procedure OTTER(sos, usable) \n         *   inputs: sos, a set of support-clauses defining the problem (a global variable) \n         *   usable, background knowledge potentially relevant to the problem\n         * </pre>\n         */\n\tprivate InferenceResult otter(OTTERAnswerHandler ansHandler,\n\t\tIndexedClauses idxdClauses, List<Clause> sos, List<Clause> usable)\n\t{\n\n\t    getLightestClauseHeuristic().initialSOS(sos);\n\n\t    // * repeat\n\t    do\n\t    {\n\t\t// * clause <- the lightest member of sos\n\t\tClause clause = getLightestClauseHeuristic().getLightestClause();\n\t\tif (null != clause)\n\t\t{\n\t\t    // * move clause from sos to usable\n\t\t    sos.Remove(clause);\n\t\t    getLightestClauseHeuristic().removedClauseFromSOS(clause);\n\t\t    usable.Add(clause);\n\t\t    // * PROCESS(INFER(clause, usable), sos)\n\t\t    process(ansHandler, idxdClauses, infer(clause, usable), sos,\n\t\t\t    usable);\n\t\t}\n\t\t// * until sos = [] or a refutation has been found\n\t    } while (sos.Count != 0 && !ansHandler.isComplete());\n\n\t    return ansHandler;\n\t}\n\n\t/**\n         * <pre>\n         * function INFER(clause, usable) returns clauses\n         */\n\tprivate List<Clause> infer(Clause clause, List<Clause> usable)\n\t{\n\t    List<Clause> resultingClauses = new List<Clause>();\n\t    // * resolve clause with each member of usable\n\t    foreach (Clause c in usable)\n\t    {\n\t\tList<Clause> resolvents = clause.binaryResolvents(c);\n\t\tforeach (Clause rc in resolvents)\n\t\t{\n\t\t    resultingClauses.Add(rc);\n\t\t}\n\n\t\t// if using paramodulation to handle equality\n\t\tif (isUseParamodulation())\n\t\t{\n\t\t    List<Clause> paras = paramodulation.apply(clause, c, true);\n\t\t    foreach (Clause p in paras)\n\t\t    {\n\t\t\tresultingClauses.Add(p);\n\t\t    }\n\t\t}\n\t    }\n\n\t    // * return the resulting clauses after applying filter\n\t    return getClauseFilter().filter(new HashSet<Clause>(resultingClauses)).ToList();\n\t}\n\n\t// procedure PROCESS(clauses, sos)\n\tprivate void process(OTTERAnswerHandler ansHandler,\n\t\tIndexedClauses idxdClauses, List<Clause> clauses, List<Clause> sos,\n\t\tList<Clause> usable)\n\t{\n\n\t    // * for each clause in clauses do\n\t    foreach (Clause clause in clauses)\n\t    {\n\t\t// * clause <- SIMPLIFY(clause)\n\t\tClause clause2 = getClauseSimplifier().simplify(clause);\n\n\t\t// * merge identical literals\n\t\t// Note: Not required as handled by Clause Implementation\n\t\t// which keeps literals within a Set, so no duplicates\n\t\t// will exist.\n\n\t\t// * discard clause if it is a tautology\n\t\tif (clause2.isTautology())\n\t\t{\n\t\t    continue;\n\t\t}\n\n\t\t// * if clause has no literals then a refutation has been found\n\t\t// or if it just contains the answer literal.\n\t\tif (!ansHandler.isAnswer(clause2))\n\t\t{\n\t\t    // * sos <- [clause | sos]\n\t\t    // This check ensure duplicate clauses are not\n\t\t    // introduced which will cause the\n\t\t    // LightestClauseHeuristic to loop continuously\n\t\t    // on the same pair of objects.\n\t\t    if (!sos.Contains(clause2) && !usable.Contains(clause2))\n\t\t    {\n\t\t\tforeach (Clause ac in clause2.getFactors())\n\t\t\t{\n\t\t\t    if (!sos.Contains(ac) && !usable.Contains(ac))\n\t\t\t    {\n\t\t\t\tidxdClauses.addClause(ac, sos, usable);\n\n\t\t\t\t// * if clause has one literal then look for unit\n\t\t\t\t// refutation\n\t\t\t\tlookForUnitRefutation(ansHandler, idxdClauses, ac,\n\t\t\t\t\tsos, usable);\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\n\t\tif (ansHandler.isComplete())\n\t\t{\n\t\t    break;\n\t\t}\n\t    }\n\t}\n\n\tprivate void lookForUnitRefutation(OTTERAnswerHandler ansHandler,\n\t\tIndexedClauses idxdClauses, Clause clause, List<Clause> sos,\n\t\tList<Clause> usable)\n\t{\n\n\t    List<Clause> toCheck = new List<Clause>();\n\n\t    if (ansHandler.isCheckForUnitRefutation(clause))\n\t    {\n\t\tforeach (Clause s in sos)\n\t\t{\n\t\t    if (s.isUnitClause())\n\t\t    {\n\t\t\ttoCheck.Add(s);\n\t\t    }\n\t\t}\n\t\tforeach (Clause u in usable)\n\t\t{\n\t\t    if (u.isUnitClause())\n\t\t    {\n\t\t\ttoCheck.Add(u);\n\t\t    }\n\t\t}\n\t    }\n\n\t    if (toCheck.Count > 0)\n\t    {\n\t\ttoCheck = infer(clause, toCheck);\n\t\tforeach (Clause t in toCheck)\n\t\t{\n\t\t    // * clause <- SIMPLIFY(clause)\n\t\t    Clause t2 = getClauseSimplifier().simplify(t);\n\n\t\t    // * discard clause if it is a tautology\n\t\t    if (t2.isTautology())\n\t\t    {\n\t\t\tcontinue;\n\t\t    }\n\n\t\t    // * if clause has no literals then a refutation has been found\n\t\t    // or if it just contains the answer literal.\n\t\t    if (!ansHandler.isAnswer(t2))\n\t\t    {\n\t\t\t// * sos <- [clause | sos]\n\t\t\t// This check ensure duplicate clauses are not\n\t\t\t// introduced which will cause the\n\t\t\t// LightestClauseHeuristic to loop continuously\n\t\t\t// on the same pair of objects.\n\t\t\tif (!sos.Contains(t2) && !usable.Contains(t2))\n\t\t\t{\n\t\t\t    idxdClauses.addClause(t2, sos, usable);\n\t\t\t}\n\t\t    }\n\n\t\t    if (ansHandler.isComplete())\n\t\t    {\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\t// This is a simple indexing on the clauses to support\n\t// more efficient forward and backward subsumption testing.\n\tclass IndexedClauses\n\t{\n\t    private LightestClauseHeuristic lightestClauseHeuristic = null;\n\t    // Group the clauses by their # of literals.\n\t    private Dictionary<int, List<Clause>> clausesGroupedBySize = new Dictionary<int, List<Clause>>();\n\t    // Keep track of the min and max # of literals.\n\t    private int minNoLiterals = int.MaxValue;\n\t    private int maxNoLiterals = 0;\n\n\t    public IndexedClauses(LightestClauseHeuristic lightestClauseHeuristic,\n\t\t    List<Clause> sos, List<Clause> usable)\n\t    {\n\t\tthis.lightestClauseHeuristic = lightestClauseHeuristic;\n\t\tforeach (Clause c in sos)\n\t\t{\n\t\t    indexClause(c);\n\t\t}\n\t\tforeach (Clause c in usable)\n\t\t{\n\t\t    indexClause(c);\n\t\t}\n\t    }\n\n\t    public void addClause(Clause c, List<Clause> sos, List<Clause> usable)\n\t    {\n\t\t// Perform forward subsumption elimination\n\t\tbool addToSOS = true;\n\t\tfor (int i = minNoLiterals; i < c.getNumberLiterals(); i++)\n\t\t{\n\t\t    List<Clause> fs = clausesGroupedBySize[i];\n\t\t    if (null != fs)\n\t\t    {\n\t\t\tforeach (Clause s in fs)\n\t\t\t{\n\t\t\t    if (s.subsumes(c))\n\t\t\t    {\n\t\t\t\taddToSOS = false;\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t    if (!addToSOS)\n\t\t    {\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\n\t\tif (addToSOS)\n\t\t{\n\t\t    sos.Add(c);\n\t\t    lightestClauseHeuristic.addedClauseToSOS(c);\n\t\t    indexClause(c);\n\t\t    // Have added clause, therefore\n\t\t    // perform backward subsumption elimination\n\t\t    List<Clause> subsumed = new List<Clause>();\n\t\t    for (int i = c.getNumberLiterals() + 1; i <= maxNoLiterals; i++)\n\t\t    {\n\t\t\tsubsumed.Clear();\n\t\t\tList<Clause> bs = clausesGroupedBySize[i];\n\t\t\tif (null != bs)\n\t\t\t{\n\t\t\t    foreach (Clause s in bs)\n\t\t\t    {\n\t\t\t\tif (c.subsumes(s))\n\t\t\t\t{\n\t\t\t\t    subsumed.Add(s);\n\t\t\t\t    if (sos.Contains(s))\n\t\t\t\t    {\n\t\t\t\t\tsos.Remove(s);\n\t\t\t\t\tlightestClauseHeuristic\n\t\t\t\t\t\t.removedClauseFromSOS(s);\n\t\t\t\t    }\n\t\t\t\t    usable.Remove(s);\n\t\t\t\t}\n\t\t\t    }\n\t\t\t    foreach (Clause c2 in subsumed)\n\t\t\t    {\n\t\t\t\tbs.Remove(c2);\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\n\t    // PRIVATE METHODS\n\n\t    private void indexClause(Clause c)\n\t    {\n\t\tint size = c.getNumberLiterals();\n\t\tif (size < minNoLiterals)\n\t\t{\n\t\t    minNoLiterals = size;\n\t\t}\n\t\tif (size > maxNoLiterals)\n\t\t{\n\t\t    maxNoLiterals = size;\n\t\t}\n\t\tList<Clause> cforsize = null;\n\t\tif (!clausesGroupedBySize.ContainsKey(size))\n\t\t{\n\t\t    cforsize = new List<Clause>();\n\t\t    clausesGroupedBySize.Add(size, cforsize);\n\t\t}\n\t\telse\n\t\t{\n\t\t    cforsize = clausesGroupedBySize[size];\n\t\t}\n\t\tcforsize.Add(c);\n\t    }\n\t}\n\n\tclass OTTERAnswerHandler : InferenceResult\n\t{\n\t    private Literal answerLiteral = null;\n\t    private List<Variable> answerLiteralVariables = null;\n\t    private Clause answerClause = null;\n\t    private long finishTime = 0L;\n\t    private bool complete = false;\n\t    private List<Proof> proofs = new List<Proof>();\n\t    private bool timedOut = false;\n\n\t    public OTTERAnswerHandler(Literal answerLiteral,\n\t\t    List<Variable> answerLiteralVariables, Clause answerClause,\n\t\t    long maxQueryTime)\n\t    {\n\t\tthis.answerLiteral = answerLiteral;\n\t\tthis.answerLiteralVariables = answerLiteralVariables;\n\t\tthis.answerClause = answerClause;\n\t\t//\n\t\tthis.finishTime = DateTime.UtcNow.Ticks + maxQueryTime;\n\t    }\n\n\t    // START-InferenceResult\n\t    public bool isPossiblyFalse()\n\t    {\n\t\treturn !timedOut && proofs.Count == 0;\n\t    }\n\n\t    public bool isTrue()\n\t    {\n\t\treturn proofs.Count > 0;\n\t    }\n\n\t    public bool isUnknownDueToTimeout()\n\t    {\n\t\treturn timedOut && proofs.Count == 0;\n\t    }\n\n\t    public bool isPartialResultDueToTimeout()\n\t    {\n\t\treturn timedOut && proofs.Count > 0;\n\t    }\n\n\t    public List<Proof> getProofs()\n\t    {\n\t\treturn proofs;\n\t    }\n\n\t    // END-InferenceResult\n\n\t    public bool isComplete()\n\t    {\n\t\treturn complete;\n\t    }\n\n\t    public bool isLookingForAnswerLiteral()\n\t    {\n\t\treturn !answerClause.isEmpty();\n\t    }\n\n\t    public bool isCheckForUnitRefutation(Clause clause)\n\t    {\n\n\t\tif (isLookingForAnswerLiteral())\n\t\t{\n\t\t    if (2 == clause.getNumberLiterals())\n\t\t    {\n\t\t\tforeach (Literal t in clause.getLiterals())\n\t\t\t{\n\t\t\t    if (t.getAtomicSentence().getSymbolicName().Equals(\n\t\t\t\t    answerLiteral.getAtomicSentence()\n\t\t\t\t\t    .getSymbolicName()))\n\t\t\t    {\n\t\t\t\treturn true;\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t\telse\n\t\t{\n\t\t    return clause.isUnitClause();\n\t\t}\n\n\t\treturn false;\n\t    }\n\n\t    public bool isAnswer(Clause aClause)\n\t    {\n\t\tbool isAns = false;\n\n\t\tif (answerClause.isEmpty())\n\t\t{\n\t\t    if (aClause.isEmpty())\n\t\t    {\n\t\t\tproofs.Add(new ProofFinal(aClause.getProofStep(),\n\t\t\t\tnew Dictionary<Variable, Term>()));\n\t\t\tcomplete = true;\n\t\t\tisAns = true;\n\t\t    }\n\t\t}\n\t\telse\n\t\t{\n\t\t    if (aClause.isEmpty())\n\t\t    {\n\t\t\t// This should not happen\n\t\t\t// as added an answer literal to sos, which\n\t\t\t// implies the database (i.e. premises) are\n\t\t\t// unsatisfiable to begin with.\n\t\t\tthrow new ApplicationException(\n\t\t\t\t\"Generated an empty clause while looking for an answer, implies original KB or usable is unsatisfiable\");\n\t\t    }\n\n\t\t    if (aClause.isUnitClause()\n\t\t\t    && aClause.isDefiniteClause()\n\t\t\t    && aClause.getPositiveLiterals()[0]\n\t\t\t\t    .getAtomicSentence().getSymbolicName().Equals(\n\t\t\t\t\t    answerLiteral.getAtomicSentence()\n\t\t\t\t\t\t    .getSymbolicName()))\n\t\t    {\n\t\t\tDictionary<Variable, Term> answerBindings = new Dictionary<Variable, Term>();\n\t\t\tList<Term> answerTerms = aClause.getPositiveLiterals()[\n\t\t\t\t0].getAtomicSentence().getArgs();\n\t\t\tint idx = 0;\n\t\t\tforeach (Variable v in answerLiteralVariables)\n\t\t\t{\n\t\t\t    answerBindings.Add(v, (Term)answerTerms[idx]);\n\t\t\t    idx++;\n\t\t\t}\n\t\t\tbool addNewAnswer = true;\n\t\t\tforeach (Proof p in proofs)\n\t\t\t{\n\t\t\t    if (p.getAnswerBindings().Equals(answerBindings))\n\t\t\t    {\n\t\t\t\taddNewAnswer = false;\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t\tif (addNewAnswer)\n\t\t\t{\n\t\t\t    proofs.Add(new ProofFinal(aClause.getProofStep(),\n\t\t\t\t    answerBindings));\n\t\t\t}\n\t\t\tisAns = true;\n\t\t    }\n\t\t}\n\n\t\tif (DateTime.UtcNow.Ticks > finishTime)\n\t\t{\n\t\t    complete = true;\n\t\t    // Indicate that I have run out of query time\n\t\t    timedOut = true;\n\t\t}\n\n\t\treturn isAns;\n\t    }\n\n\t    public override String ToString()\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(\"isComplete=\" + complete);\n\t\tsb.Append(\"\\n\");\n\t\tsb.Append(\"result=\" + proofs);\n\t\treturn sb.ToString();\n\t    }\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/FOLTFMResolution.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing aima.core.logic.fol;\nusing aima.core.logic.fol.inference.proof;\nusing aima.core.logic.fol.inference.trace;\nusing aima.core.logic.fol.kb;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 347.<br>\n     * <br>\n     * The algorithmic approach is identical to the propositional case, described in\n     * Figure 7.12.<br>\n     * <br>\n     * However, this implementation will use the T)wo F)inger M)ethod for looking\n     * for resolvents between clauses, which is very inefficient.<br>\n     * <br>\n     * see:<br>\n     * <a\n     * href=\"http://logic.stanford.edu/classes/cs157/2008/lectures/lecture04.pdf\">\n     * http://logic.stanford.edu/classes/cs157/2008/lectures/lecture04.pdf</a>,\n     * slide 21 for the propositional case. In addition, an Answer literal will be\n     * used so that queries with Variables may be answered (see pg. 350 of AIMA3e).\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class FOLTFMResolution : InferenceProcedure\n    {\n\tprivate long maxQueryTime = 10 * 1000;\n\n\tprivate FOLTFMResolutionTracer tracer = null;\n\n\tpublic FOLTFMResolution()\n\t{\n\n\t}\n\n\tpublic FOLTFMResolution(long maxQueryTime)\n\t{\n\t    setMaxQueryTime(maxQueryTime);\n\t}\n\n\tpublic FOLTFMResolution(FOLTFMResolutionTracer tracer)\n\t{\n\t    setTracer(tracer);\n\t}\n\n\tpublic long getMaxQueryTime()\n\t{\n\t    return maxQueryTime;\n\t}\n\n\tpublic void setMaxQueryTime(long maxQueryTime)\n\t{\n\t    this.maxQueryTime = maxQueryTime;\n\t}\n\n\tpublic FOLTFMResolutionTracer getTracer()\n\t{\n\t    return tracer;\n\t}\n\n\tpublic void setTracer(FOLTFMResolutionTracer tracer)\n\t{\n\t    this.tracer = tracer;\n\t}\n\t\n\t// START-InferenceProcedure\n\tpublic InferenceResult ask(FOLKnowledgeBase KB, Sentence alpha)\n\t{\n\n\t    // clauses <- the set of clauses in CNF representation of KB ^ ~alpha\n\t    List<Clause> clauses = new List<Clause>();\n\t    foreach (Clause c in KB.getAllClauses())\n\t    {\n\t\tClause c2 = KB.standardizeApart(c);\n\t\tc2.setStandardizedApartCheckNotRequired();\n\t\tclauses.AddRange(c2.getFactors());\n\t    }\n\t    Sentence notAlpha = new NotSentence(alpha);\n\t    // Want to use an answer literal to pull\n\t    // query variables where necessary\n\t    Literal answerLiteral = KB.createAnswerLiteral(notAlpha);\n\t    List<Variable> answerLiteralVariables = KB\n\t\t    .collectAllVariables(answerLiteral.getAtomicSentence());\n\t    Clause answerClause = new Clause();\n\n\t    if (answerLiteralVariables.Count > 0)\n\t    {\n\t\tSentence notAlphaWithAnswer = new ConnectedSentence(Connectors.OR,\n\t\t\tnotAlpha, answerLiteral.getAtomicSentence());\n\t\tforeach (Clause c in KB.convertToClauses(notAlphaWithAnswer))\n\t\t{\n\t\t    Clause c2 = KB.standardizeApart(c);\n\t\t    c2.setProofStep(new ProofStepGoal(c2));\n\t\t    c2.setStandardizedApartCheckNotRequired();\n\t\t    clauses.AddRange(c2.getFactors());\n\t\t}\n\n\t\tanswerClause.addLiteral(answerLiteral);\n\t    }\n\t    else\n\t    {\n\t\tforeach (Clause c in KB.convertToClauses(notAlpha))\n\t\t{\n\t\t    Clause c2 = KB.standardizeApart(c);\n\t\t    c2.setProofStep(new ProofStepGoal(c2));\n\t\t    c2.setStandardizedApartCheckNotRequired();\n\t\t    clauses.AddRange(c2.getFactors());\n\t\t}\n\t    }\n\n\t    TFMAnswerHandler ansHandler = new TFMAnswerHandler(answerLiteral,\n\t\t    answerLiteralVariables, answerClause, maxQueryTime);\n\n\t    // new <- {}\n\t    List<Clause> newClauses = new List<Clause>();\n\t    List<Clause> toAdd = new List<Clause>();\n\t    // loop do\n\t    int noOfPrevClauses = clauses.Count;\n\t    do\n\t    {\n\t\tif (null != tracer)\n\t\t{\n\t\t    tracer.stepStartWhile(new HashSet<Clause>(clauses), clauses.Count, newClauses\n\t\t\t    .Count);\n\t\t}\n\n\t\tnewClauses.Clear();\n\n\t\t// for each Ci, Cj in clauses do\n\t\tClause[] clausesA = new Clause[clauses.Count];\n\t\tclausesA = clauses.ToArray();\n\t\t// Basically, using the simple T)wo F)inger M)ethod here.\n\t\tfor (int i = 0; i < clausesA.Length; i++)\n\t\t{\n\t\t    Clause cI = clausesA[i];\n\t\t    if (null != tracer)\n\t\t    {\n\t\t\ttracer.stepOuterFor(cI);\n\t\t    }\n\t\t    for (int j = i; j < clausesA.Length; j++)\n\t\t    {\n\t\t\tClause cJ = clausesA[j];\n\n\t\t\tif (null != tracer)\n\t\t\t{\n\t\t\t    tracer.stepInnerFor(cI, cJ);\n\t\t\t}\n\n\t\t\t// resolvent <- FOL-RESOLVE(Ci, Cj)\n\t\t\tList<Clause> resolvents = cI.binaryResolvents(cJ);\n\n\t\t\tif (resolvents.Count > 0)\n\t\t\t{\n\t\t\t    toAdd.Clear();\n\t\t\t    // new <- new <UNION> resolvent\n\t\t\t    foreach (Clause rc in resolvents)\n\t\t\t    {\n\t\t\t\ttoAdd.AddRange(rc.getFactors());\n\t\t\t    }\n\n\t\t\t    if (null != tracer)\n\t\t\t    {\n\t\t\t\ttracer.stepResolved(cI, cJ, new HashSet<Clause>(toAdd));\n\t\t\t    }\n\n\t\t\t    ansHandler.checkForPossibleAnswers(toAdd);\n\n\t\t\t    if (ansHandler.isComplete())\n\t\t\t    {\n\t\t\t\tbreak;\n\t\t\t    }\n\n\t\t\t    newClauses.AddRange(toAdd);\n\t\t\t}\n\n\t\t\tif (ansHandler.isComplete())\n\t\t\t{\n\t\t\t    break;\n\t\t\t}\n\t\t    }\n\t\t    if (ansHandler.isComplete())\n\t\t    {\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\n\t\tnoOfPrevClauses = clauses.Count;\n\n\t\t// clauses <- clauses <UNION> new\n\t\tclauses.AddRange(newClauses);\n\n\t\tif (ansHandler.isComplete())\n\t\t{\n\t\t    break;\n\t\t}\n\n\t\t// if new is a <SUBSET> of clauses then finished\n\t\t// searching for an answer\n\t\t// (i.e. when they were added the # clauses\n\t\t// did not increase).\n\t    } while (noOfPrevClauses < clauses.Count);\n\n\t    if (null != tracer)\n\t    {\n\t\ttracer.stepFinished(new HashSet<Clause>(clauses), ansHandler);\n\t    }\n\n\t    return ansHandler;\n\t}\n\n\t// END-InferenceProcedure\n\t// \n\n\t//\n\t// PRIVATE METHODS\n\t//\n\tclass TFMAnswerHandler : InferenceResult\n\t{\n\t    private Literal answerLiteral = null;\n\t    private List<Variable> answerLiteralVariables = null;\n\t    private Clause answerClause = null;\n\t    private long finishTime = 0L;\n\t    private bool complete = false;\n\t    private List<Proof> proofs = new List<Proof>();\n\t    private bool timedOut = false;\n\n\t    public TFMAnswerHandler(Literal answerLiteral,\n\t\t    List<Variable> answerLiteralVariables, Clause answerClause,\n\t\t    long maxQueryTime)\n\t    {\n\t\tthis.answerLiteral = answerLiteral;\n\t\tthis.answerLiteralVariables = answerLiteralVariables;\n\t\tthis.answerClause = answerClause;\n\t\t//\n\t\tthis.finishTime = DateTime.UtcNow.Ticks + maxQueryTime;\n\t    }\n\n\t    //\n\t    // START-InferenceResult\n\t    public bool isPossiblyFalse()\n\t    {\n\t\treturn !timedOut && proofs.Count == 0;\n\t    }\n\n\t    public bool isTrue()\n\t    {\n\t\treturn proofs.Count > 0;\n\t    }\n\n\t    public bool isUnknownDueToTimeout()\n\t    {\n\t\treturn timedOut && proofs.Count == 0;\n\t    }\n\n\t    public bool isPartialResultDueToTimeout()\n\t    {\n\t\treturn timedOut && proofs.Count > 0;\n\t    }\n\n\t    public List<Proof> getProofs()\n\t    {\n\t\treturn proofs;\n\t    }\n\n\t    // END-InferenceResult\n\t    \n\t    public bool isComplete()\n\t    {\n\t\treturn complete;\n\t    }\n\n\t    public void checkForPossibleAnswers(List<Clause> resolvents)\n\t    {\n\t\t// If no bindings being looked for, then\n\t\t// is just a true false query.\n\t\tforeach (Clause aClause in resolvents)\n\t\t{\n\t\t    if (answerClause.isEmpty())\n\t\t    {\n\t\t\tif (aClause.isEmpty())\n\t\t\t{\n\t\t\t    proofs.Add(new ProofFinal(aClause.getProofStep(),\n\t\t\t\t    new Dictionary<Variable, Term>()));\n\t\t\t    complete = true;\n\t\t\t}\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\tif (aClause.isEmpty())\n\t\t\t{\n\t\t\t    // This should not happen\n\t\t\t    // as added an answer literal, which\n\t\t\t    // implies the database (i.e. premises) are\n\t\t\t    // unsatisfiable to begin with.\n\t\t\t    throw new ApplicationException(\n\t\t\t\t    \"Generated an empty clause while looking for an answer, implies original KB is unsatisfiable\");\n\t\t\t}\n\n\t\t\tif (aClause.isUnitClause()\n\t\t\t\t&& aClause.isDefiniteClause()\n\t\t\t\t&& aClause.getPositiveLiterals()[0]\n\t\t\t\t\t.getAtomicSentence().getSymbolicName()\n\t\t\t\t\t.Equals(\n\t\t\t\t\t\tanswerLiteral.getAtomicSentence()\n\t\t\t\t\t\t\t.getSymbolicName()))\n\t\t\t{\n\t\t\t    Dictionary<Variable, Term> answerBindings = new Dictionary<Variable, Term>();\n\t\t\t    List<Term> answerTerms = aClause.getPositiveLiterals()\n\t\t\t\t    [0].getAtomicSentence().getArgs();\n\t\t\t    int idx = 0;\n\t\t\t    foreach (Variable v in answerLiteralVariables)\n\t\t\t    {\n\t\t\t\tanswerBindings.Add(v, (Term)answerTerms[idx]);\n\t\t\t\tidx++;\n\t\t\t    }\n\t\t\t    bool addNewAnswer = true;\n\t\t\t    foreach (Proof p in proofs)\n\t\t\t    {\n\t\t\t\tif (p.getAnswerBindings().Equals(answerBindings))\n\t\t\t\t{\n\t\t\t\t    addNewAnswer = false;\n\t\t\t\t    break;\n\t\t\t\t}\n\t\t\t    }\n\t\t\t    if (addNewAnswer)\n\t\t\t    {\n\t\t\t\tproofs.Add(new ProofFinal(aClause.getProofStep(),\n\t\t\t\t\tanswerBindings));\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\n\t\t    if (DateTime.UtcNow.Ticks > finishTime)\n\t\t    {\n\t\t\tcomplete = true;\n\t\t\t// Indicate that I have run out of query time\n\t\t\ttimedOut = true;\n\t\t    }\n\t\t}\n\t    }\n\n\t    public override String ToString()\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(\"isComplete=\" + complete);\n\t\tsb.Append(\"\\n\");\n\t\tsb.Append(\"result=\" + proofs);\n\t\treturn sb.ToString();\n\t    }\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/logic/fol/inference/InferenceProcedure.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.kb;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface InferenceProcedure\n    {\n\t/**\n\t * \n\t * @param kb\n\t *            the knowledge base against which the query is to be made.\n\t * @param query\n\t *            the query to be answered.\n\t * @return an InferenceResult.\n\t */\n\tInferenceResult ask(FOLKnowledgeBase kb, Sentence query);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/InferenceResult.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.inference.proof;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface InferenceResult\n    {\n\t/**\n\t * \n\t * @return true, if the query is not entailed from the premises. This just\n\t *         means the query is not entailed, the query itself may be true.\n\t */\n\tbool isPossiblyFalse();\n\n\t/**\n\t * \n\t * @return true, if the query is entailed from the premises (Note: can get\n\t *         partial results if the original query contains variables\n\t *         indicating that there can possibly be more than 1 proof/bindings\n\t *         for the query, see: isPartialResultDueToTimeout()).\n\t */\n\tbool isTrue();\n\n\t/**\n\t * \n\t * @return true, if the inference procedure ran for a length of time and\n\t *         found no proof one way or the other before it timed out.\n\t */\n\tbool isUnknownDueToTimeout();\n\n\t/**\n\t * \n\t * @return true, if the inference procedure found a proof for a query\n\t *         containing variables (i.e. possibly more than 1 proof can be\n\t *         returned) and the inference procedure was still looking for other\n\t *         possible answers before it timed out.\n\t */\n\tbool isPartialResultDueToTimeout();\n\n\t/**\n\t * \n\t * @return a list of 0 or more proofs (multiple proofs can be returned if\n\t *         the original query contains variables).\n\t */\n\tList<Proof> getProofs();\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/InferenceResultPrinter.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing aima.core.logic.fol.inference.proof;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class InferenceResultPrinter\n    {\n\t/**\n         * Utility method for outputting InferenceResults in a formatted textual\n         * representation.\n         * \n         * @param ir\n         *            an InferenceResult\n         * @return a String representation of the InferenceResult.\n         */\n\tpublic static String printInferenceResult(InferenceResult ir)\n\t{\n\t    StringBuilder sb = new StringBuilder();\n\n\t    sb.Append(\"InferenceResult.isTrue=\" + ir.isTrue());\n\t    sb.Append(\"\\n\");\n\t    sb.Append(\"InferenceResult.isPossiblyFalse=\" + ir.isPossiblyFalse());\n\t    sb.Append(\"\\n\");\n\t    sb.Append(\"InferenceResult.isUnknownDueToTimeout=\"\n\t\t\t    + ir.isUnknownDueToTimeout());\n\t    sb.Append(\"\\n\");\n\t    sb.Append(\"InferenceResult.isPartialResultDueToTimeout=\"\n\t\t\t    + ir.isPartialResultDueToTimeout());\n\t    sb.Append(\"\\n\");\n\t    sb.Append(\"InferenceResult.#Proofs=\" + ir.getProofs().Count);\n\t    sb.Append(\"\\n\");\n\t    int proofNo = 0;\n\t    List<Proof> proofs = ir.getProofs();\n\t    foreach (Proof p in proofs)\n\t    {\n\t\tproofNo++;\n\t\tsb.Append(\"InferenceResult.Proof#\" + proofNo + \"=\\n\"\n\t\t\t\t+ ProofPrinter.printProof(p));\n\t    }\n\t    return sb.ToString();\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/Paramodulation.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol;\nusing aima.core.logic.fol.inference.proof;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3r Edition): page 354.<br>\n     * <br>\n     * <b>Paramodulation</b>: For any terms x, y, and z, where z appears somewhere\n     * in literal m<sub>i</sub>, and where UNIFY(x,z) = &theta;,<br>\n     * \n     * <pre>\n     *                          l<sub>1</sub> OR ... OR l<sub>k</sub> OR x=y,     m<sub>1</sub> OR ... OR m<sub>n</sub>\n     *     ------------------------------------------------------------------------\n     *     SUB(SUBST(&theta;,x), SUBST(&theta;,y), SUBST(&theta;, l<sub>1</sub> OR ... OR l<sub>k</sub> OR m<sub>1</sub> OR ... OR m<sub>n</sub>))\n     * </pre>\n     * \n     * Paramodulation yields a complete inference procedure for first-order logic\n     * with equality.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class Paramodulation : AbstractModulation\n    {\n\tprivate static StandardizeApartIndexical _saIndexical = StandardizeApartIndexicalFactory\n\t\t.newStandardizeApartIndexical('p');\n\tprivate static List<Literal> _emptyLiteralList = new List<Literal>();\n\t\n\tprivate StandardizeApart sApart = new StandardizeApart();\n\n\tpublic Paramodulation()\n\t{\n\n\t}\n\n\tpublic List<Clause> apply(Clause c1, Clause c2)\n\t{\n\t    return apply(c1, c2, false);\n\t}\n\n\tpublic List<Clause> apply(Clause c1, Clause c2, bool standardizeApart)\n\t{\n\t    List<Clause> paraExpressions = new List<Clause>();\n\n\t    for (int i = 0; i < 2; i++)\n\t    {\n\t\tClause topClause, equalityClause;\n\t\tif (i == 0)\n\t\t{\n\t\t    topClause = c1;\n\t\t    equalityClause = c2;\n\t\t}\n\t\telse\n\t\t{\n\t\t    topClause = c2;\n\t\t    equalityClause = c1;\n\t\t}\n\n\t\tforeach (Literal possEqLit in equalityClause.getLiterals())\n\t\t{\n\t\t    // Must be a positive term equality to be used\n\t\t    // for paramodulation.\n\t\t    if (possEqLit.isPositiveLiteral()\n\t\t\t    && possEqLit.getAtomicSentence() is TermEquality)\n\t\t    {\n\t\t\tTermEquality assertion = (TermEquality)possEqLit\n\t\t\t\t.getAtomicSentence();\n\n\t\t\t// Test matching for both sides of the equality\n\t\t\tfor (int x = 0; x < 2; x++)\n\t\t\t{\n\t\t\t    Term toMatch, toReplaceWith;\n\t\t\t    if (x == 0)\n\t\t\t    {\n\t\t\t\ttoMatch = assertion.getTerm1();\n\t\t\t\ttoReplaceWith = assertion.getTerm2();\n\t\t\t    }\n\t\t\t    else\n\t\t\t    {\n\t\t\t\ttoMatch = assertion.getTerm2();\n\t\t\t\ttoReplaceWith = assertion.getTerm1();\n\t\t\t    }\n\n\t\t\t    foreach (Literal l1 in topClause.getLiterals())\n\t\t\t    {\n\t\t\t\tIdentifyCandidateMatchingTerm icm = getMatchingSubstitution(\n\t\t\t\t\ttoMatch, l1.getAtomicSentence());\n\n\t\t\t\tif (null != icm)\n\t\t\t\t{\n\t\t\t\t    Term replaceWith = substVisitor.subst(icm\n\t\t\t\t\t    .getMatchingSubstitution(),\n\t\t\t\t\t    toReplaceWith);\n\n\t\t\t\t    // Want to ignore reflexivity axiom situation,\n\t\t\t\t    // i.e. x = x\n\t\t\t\t    if (icm.getMatchingTerm().Equals(replaceWith))\n\t\t\t\t    {\n\t\t\t\t\tcontinue;\n\t\t\t\t    }\n\n\t\t\t\t    ReplaceMatchingTerm rmt = new ReplaceMatchingTerm();\n\n\t\t\t\t    AtomicSentence altExpression = rmt.replace(l1\n\t\t\t\t\t    .getAtomicSentence(), icm\n\t\t\t\t\t    .getMatchingTerm(), replaceWith);\n\n\t\t\t\t    // I have an alternative, create a new clause\n\t\t\t\t    // with the alternative and the substitution\n\t\t\t\t    // applied to all the literals before returning\n\t\t\t\t    List<Literal> newLits = new List<Literal>();\n\t\t\t\t    foreach (Literal l2 in topClause.getLiterals())\n\t\t\t\t    {\n\t\t\t\t\tif (l1.Equals(l2))\n\t\t\t\t\t{\n\t\t\t\t\t    newLits\n\t\t\t\t\t\t    .Add(l1\n\t\t\t\t\t\t\t    .newInstance((AtomicSentence)substVisitor\n\t\t\t\t\t\t\t\t    .subst(\n\t\t\t\t\t\t\t\t\t    icm\n\t\t\t\t\t\t\t\t\t\t    .getMatchingSubstitution(),\n\t\t\t\t\t\t\t\t\t    altExpression)));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t    newLits\n\t\t\t\t\t\t    .Add(substVisitor\n\t\t\t\t\t\t\t    .subst(\n\t\t\t\t\t\t\t\t    icm\n\t\t\t\t\t\t\t\t\t    .getMatchingSubstitution(),\n\t\t\t\t\t\t\t\t    l2));\n\t\t\t\t\t}\n\t\t\t\t    }\n\t\t\t\t    // Assign the equality clause literals,\n\t\t\t\t    // excluding\n\t\t\t\t    // the term equality used.\n\t\t\t\t    foreach (Literal l2 in equalityClause.getLiterals())\n\t\t\t\t    {\n\t\t\t\t\tif (possEqLit.Equals(l2))\n\t\t\t\t\t{\n\t\t\t\t\t    continue;\n\t\t\t\t\t}\n\t\t\t\t\tnewLits.Add(substVisitor.subst(icm\n\t\t\t\t\t\t.getMatchingSubstitution(), l2));\n\t\t\t\t    }\n\n\t\t\t\t    // Only apply paramodulation at most once\n\t\t\t\t    // for each term equality.\n\t\t\t\t    Clause nc = null;\n\t\t\t\t    if (standardizeApart)\n\t\t\t\t    {\n\t\t\t\t\tsApart.standardizeApart(newLits,\n\t\t\t\t\t\t_emptyLiteralList, _saIndexical);\n\t\t\t\t\tnc = new Clause(newLits);\n\n\t\t\t\t    }\n\t\t\t\t    else\n\t\t\t\t    {\n\t\t\t\t\tnc = new Clause(newLits);\n\t\t\t\t    }\n\t\t\t\t    nc\n\t\t\t\t\t    .setProofStep(new ProofStepClauseParamodulation(\n\t\t\t\t\t\t    nc, topClause, equalityClause,\n\t\t\t\t\t\t    assertion));\n\t\t\t\t    if (c1.isImmutable())\n\t\t\t\t    {\n\t\t\t\t\tnc.setImmutable();\n\t\t\t\t    }\n\t\t\t\t    if (!c1.isStandardizedApartCheckRequired())\n\t\t\t\t    {\n\t\t\t\t\tc1.setStandardizedApartCheckNotRequired();\n\t\t\t\t    }\n\t\t\t\t    paraExpressions.Add(nc);\n\t\t\t\t    break;\n\t\t\t\t}\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t    return paraExpressions;\n\t}\n\t\n\t// PROTECTED METHODS\n\t\n\tpublic override bool isValidMatch(Term toMatch,\n\t\tList<Variable> toMatchVariables, Term possibleMatch,\n\t\tDictionary<Variable, Term> substitution)\n\t{\n\n\t    if (possibleMatch != null && substitution != null)\n\t    {\n\t\t// Note:\n\t\t// [Brand 1975] showed that paramodulation into\n\t\t// variables is unnecessary.\n\t\tif (!(possibleMatch is Variable))\n\t\t{\n\t\t    // TODO: Find out whether the following statement from:\n\t\t    // http://www.cs.miami.edu/~geoff/Courses/CSC648-07F/Content/\n\t\t    // Paramodulation.shtml\n\t\t    // is actually the case, as it was not positive but\n\t\t    // intuitively makes sense:\n\t\t    // \"Similarly, depending on how paramodulation is used, it is\n\t\t    // often unnecessary to paramodulate from variables.\"\n\t\t    // if (!(toMatch is Variable)) {\n\t\t    return true;\n\t\t    // }\n\t\t}\n\t    }\n\t    return false;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/otter/ClauseFilter.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.otter\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface ClauseFilter\n    {\n\tHashSet<Clause> filter(HashSet<Clause> clauses);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/otter/ClauseSimplifier.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.otter\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface ClauseSimplifier\n    {\n\tClause simplify(Clause c);\n    }\n}\n"
  },
  {
    "path": "aima-csharp/logic/fol/inference/otter/LightestClauseHeuristic.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.otter\n{\n    /**\n     * Heuristic for selecting lightest clause from SOS. To avoid recalculating the\n     * lightest clause on every call, the interface supports defining the initial\n     * sos and updates to that set so that it can maintain its own internal data\n     * structures to allow for incremental re-calculation of the lightest clause.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface LightestClauseHeuristic\n    {\n\t/**\n\t * Get the lightest clause from the SOS\n\t * \n\t * @return the lightest clause.\n\t */\n\tClause getLightestClause();\n\n\t/**\n\t * SOS life-cycle methods allowing implementations of this interface to\n\t * incrementally update the calculation of the lightest clause as opposed to\n\t * having to recalculate each time.\n\t * \n\t * @param clauses\n\t */\n\tvoid initialSOS(List<Clause> clauses);\n\n\tvoid addedClauseToSOS(Clause clause);\n\n\tvoid removedClauseFromSOS(Clause clause);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/otter/defaultimpl/DefaultClauseFilter.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.inference.otter;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.otter.defaultimpl\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class DefaultClauseFilter : ClauseFilter\n    {\n\tpublic DefaultClauseFilter()\n\t{\n\n\t}\n\n\t// START-ClauseFilter\n\n\tpublic HashSet<Clause> filter(HashSet<Clause> clauses)\n\t{\n\t    return clauses;\n\t}\n\n\t// END-ClauseFilter\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/otter/defaultimpl/DefaultClauseSimplifier.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing aima.core.logic.fol.inference;\nusing aima.core.logic.fol.inference.otter;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.otter.defaultimpl\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class DefaultClauseSimplifier : ClauseSimplifier\n    {\n\tprivate Demodulation demodulation = new Demodulation();\n\tprivate List<TermEquality> rewrites = new List<TermEquality>();\n\n\tpublic DefaultClauseSimplifier()\n\t{\n\n\t}\n\n\tpublic DefaultClauseSimplifier(List<TermEquality> rewrites)\n\t{\n\t    this.rewrites.AddRange(rewrites);\n\t}\n\n\t// START-ClauseSimplifier\n\n\tpublic Clause simplify(Clause c)\n\t{\n\t    Clause simplified = c;\n\n\t    // Apply each of the rewrite rules to\n\t    // the clause\n\t    foreach (TermEquality te in rewrites)\n\t    {\n\t\tClause dc = simplified;\n\t\t// Keep applying the rewrite as many times as it\n\t\t// can be applied before moving on to the next one.\n\t\twhile (null != (dc = demodulation.apply(te, dc)))\n\t\t{\n\t\t    simplified = dc;\n\t\t}\n\t    }\n\n\t    return simplified;\n\t}\n\n\t// END-ClauseSimplifier\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/otter/defaultimpl/DefaultLightestClauseHeuristic.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing aima.core.logic.fol.inference.otter;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.otter.defaultimpl\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class DefaultLightestClauseHeuristic : LightestClauseHeuristic\n    {\n\tprivate SortedSet<Clause> sos;\n\n\tpublic DefaultLightestClauseHeuristic()\n\t{\n\t    LightestClauseSorter c = new LightestClauseSorter();\n\t    sos = new SortedSet<Clause>(c);\n\t}\n\n\t// START-LightestClauseHeuristic\n\n\tpublic Clause getLightestClause()\n\t{\n\t    Clause lightest = null;\n\n\t    if (sos.Count > 0)\n\t    {\n\t\tlightest = sos.First<Clause>();\n\t    }\n\n\t    return lightest;\n\t}\n\n\tpublic void initialSOS(List<Clause> clauses)\n\t{\n\t    sos.Clear();\n\t    sos.UnionWith(clauses);\n\t}\n\n\tpublic void addedClauseToSOS(Clause clause)\n\t{\n\t    sos.Add(clause);\n\t}\n\n\tpublic void removedClauseFromSOS(Clause clause)\n\t{\n\t    sos.Remove(clause);\n\t}\n\n\t// END-LightestClauseHeuristic\n    }\n\n    class LightestClauseSorter : IComparer<Clause>\n    {\n\tpublic int Compare(Clause c1, Clause c2)\n\t{\n\t    if (c1.Equals(c2))\n\t    {\n\t\treturn 0;\n\t    }\n\t    int c1Val = c1.getNumberLiterals();\n\t    int c2Val = c2.getNumberLiterals();\n\t    return (c1Val < c2Val ? -1\n\t\t    : (c1Val == c2Val ? (compareEqualityIdentities(c1, c2)) : 1));\n\t}\n\n\tprivate int compareEqualityIdentities(Clause c1, Clause c2)\n\t{\n\t    int c1Len = c1.getEqualityIdentity().Length;\n\t    int c2Len = c2.getEqualityIdentity().Length;\n\n\t    return (c1Len < c2Len ? -1 : (c1Len == c2Len ? c1.getEqualityIdentity()\n\t\t    .CompareTo(c2.getEqualityIdentity()) : 1));\n\t}\t\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/AbstractProofStep.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public abstract class AbstractProofStep : ProofStep\n    {\n\tprivate int step = 0;\n\n\tpublic AbstractProofStep()\n\t{\n\n\t}\n\n\t// START-ProofStep\n\n\tpublic int getStepNumber()\n\t{\n\t    return step;\n\t}\n\n\tpublic void setStepNumber(int step)\n\t{\n\t    this.step = step;\n\t}\n\n\tpublic abstract List<ProofStep> getPredecessorSteps();\n\n\tpublic abstract String getProof();\n\n\tpublic abstract String getJustification();\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/Proof.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface Proof\n    {\n\t/**\n\t * \n\t * @return A list of proof steps that show how an answer was derived.\n\t */\n\tList<ProofStep> getSteps();\n\n\t/**\n\t * \n\t * @return a Map of bindings for any variables that were in the original\n\t *         query. Will be an empty Map if no variables existed in the\n\t *         original query.\n\t */\n\tDictionary<Variable, Term> getAnswerBindings();\n\n\t/**\n\t * \n\t * @param updatedBindings\n\t *            allows for the bindings to be renamed. Note: should not be\n\t *            used for any other reason.\n\t */\n\tvoid replaceAnswerBindings(Dictionary<Variable, Term> updatedBindings);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofFinal.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofFinal : Proof\n    {\n\tprivate Dictionary<Variable, Term> answerBindings = new Dictionary<Variable, Term>();\n\tprivate ProofStep finalStep = null;\n\tprivate List<ProofStep> proofSteps = null;\n\n\tpublic ProofFinal(ProofStep finalStep, Dictionary<Variable, Term> answerBindings)\n\t{\n\t    this.finalStep = finalStep;\n\t    this.answerBindings = answerBindings;\n\t}\n\n\t// START-Proof\n\n\tpublic List<ProofStep> getSteps()\n\t{\n\t    // Only calculate if the proof steps are actually requested.\n\t    if (null == proofSteps)\n\t    {\n\t\tcalculateProofSteps();\n\t    }\n\t    return proofSteps;\n\t}\n\n\tpublic Dictionary<Variable, Term> getAnswerBindings()\n\t{\n\t    return answerBindings;\n\t}\n\n\tpublic void replaceAnswerBindings(Dictionary<Variable, Term> updatedBindings)\n\t{\n\t    answerBindings.Clear();\n\t    answerBindings = updatedBindings;\n\t}\n\n\t// END-Proof\n\n\tpublic override String ToString()\n\t{\n\t    return answerBindings.ToString();\n\t}\n\n\t\n\t// PRIVATE METHODS\n\t\n\tprivate void calculateProofSteps()\n\t{\n\t    proofSteps = new List<ProofStep>();\n\t    addToProofSteps(finalStep);\n\n\t    // Move all premises to the front of the\n\t    // list of steps\n\t    int to = 0;\n\t    for (int i = 0; i < proofSteps.Count; i++)\n\t    {\n\t\tif (proofSteps[i] is ProofStepPremise)\n\t\t{\n\t\t    ProofStep m = proofSteps[i];\n\t\t    proofSteps.RemoveAt(i);\n\t\t    proofSteps.Insert(to, m);\n\t\t    to++;\n\t\t}\n\t    }\n\n\t    // Move the Goals after the premises\n\t    for (int i = 0; i < proofSteps.Count; i++)\n\t    {\n\t\tif (proofSteps[i] is ProofStepGoal)\n\t\t{\n\t\t    ProofStep m = proofSteps[i];\n\t\t    proofSteps.RemoveAt(i);\n\t\t    proofSteps.Insert(to, m);\n\t\t    to++;\n\t\t}\n\t    }\n\n\t    // Assign the step #s now that all the proof\n\t    // steps have been unwound\n\t    for (int i = 0; i < proofSteps.Count; i++)\n\t    {\n\t\tproofSteps[i].setStepNumber(i + 1);\n\t    }\n\t}\n\n\tprivate void addToProofSteps(ProofStep step)\n\t{\n\t    if (!proofSteps.Contains(step))\n\t    {\n\t\tproofSteps.Insert(0, step);\n\t    }\n\t    else\n\t    {\n\t\tproofSteps.Remove(step);\n\t\tproofSteps.Insert(0, step);\n\t    }\n\t    List<ProofStep> predecessors = step.getPredecessorSteps();\n\t    for (int i = predecessors.Count - 1; i >= 0; i--)\n\t    {\n\t\taddToProofSteps(predecessors[i]);\n\t    }\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofPrinter.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofPrinter\n    {\n\t/**\n\t * Utility method for outputting proofs in a formatted textual\n\t * representation.\n\t * \n\t * @param proof\n\t * @return a String representation of the Proof.\n\t */\n\tpublic static String printProof(Proof proof)\n\t{\n\t    StringBuilder sb = new StringBuilder();\n\n\t    sb.Append(\"Proof, Answer Bindings: \");\n\t    sb.Append(proof.getAnswerBindings());\n\t    sb.Append(\"\\n\");\n\n\t    List<ProofStep> steps = proof.getSteps();\n\n\t    int maxStepWidth = \"Step\".Length;\n\t    int maxProofWidth = \"Proof\".Length;\n\t    int maxJustificationWidth = \"Justification\".Length;\n\n\t    // Calculate the maximum width for each column in the proof\n\t    foreach (ProofStep step in steps)\n\t    {\n\t\tString sn = \"\" + step.getStepNumber();\n\t\tif (sn.Length > maxStepWidth)\n\t\t{\n\t\t    maxStepWidth = sn.Length;\n\t\t}\n\t\tif (step.getProof().Length > maxProofWidth)\n\t\t{\n\t\t    maxProofWidth = step.getProof().Length;\n\t\t}\n\t\tif (step.getJustification().Length > maxJustificationWidth)\n\t\t{\n\t\t    maxJustificationWidth = step.getJustification().Length;\n\t\t}\n\t    }\n\n\t    // Give a little extra padding\n\t    maxStepWidth += 1;\n\t    maxProofWidth += 1;\n\t    maxJustificationWidth += 1;\n\n\t    String f = \"|%-\" + maxStepWidth + \"s| %-\" + maxProofWidth + \"s|%-\"\n\t\t    + maxJustificationWidth + \"s|\\n\";\n\n\t    int barWidth = 5 + maxStepWidth + maxProofWidth + maxJustificationWidth;\n\t    StringBuilder bar = new StringBuilder();\n\t    for (int i = 0; i < barWidth; i++)\n\t    {\n\t\tbar.Append(\"-\");\n\t    }\n\t    bar.Append(\"\\n\");\n\n\t    sb.Append(bar);\n\t    sb.Append(String.Format(f, \"Step\", \"Proof\", \"Justification\"));\n\t    sb.Append(bar);\n\t    foreach (ProofStep step in steps)\n\t    {\n\t\tsb.Append(String.Format(f, \"\" + step.getStepNumber(), step\n\t\t\t.getProof(), step.getJustification()));\n\t    }\n\t    sb.Append(bar);\n\t    return sb.ToString();\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStep.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface ProofStep\n    {\n\tint getStepNumber();\n\n\tvoid setStepNumber(int step);\n\n\tList<ProofStep> getPredecessorSteps();\n\n\tString getProof();\n\n\tString getJustification();\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepBwChGoal.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepBwChGoal : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Clause toProve = null;\n\tprivate Literal currentGoal = null;\n\tprivate Dictionary<Variable, Term> bindings = new Dictionary<Variable, Term>();\n\n\tpublic ProofStepBwChGoal(Clause toProve, Literal currentGoal,\n\t\tDictionary<Variable, Term> bindings)\n\t{\n\t    this.toProve = toProve;\n\t    this.currentGoal = currentGoal;\n\t    foreach (Variable key in bindings.Keys)\n\t    {\n\t\tthis.bindings.Add(key, bindings[key]);\n\t    }\n\t}\n\n\tpublic Dictionary<Variable, Term> getBindings()\n\t{\n\t    return bindings;\n\t}\n\n\tpublic void setPredecessor(ProofStep predecessor)\n\t{\n\t    predecessors.Clear();\n\t    predecessors.Add(predecessor);\n\t}\n\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    StringBuilder sb = new StringBuilder();\n\t    List<Literal> nLits = toProve.getNegativeLiterals();\n\t    for (int i = 0; i < toProve.getNumberNegativeLiterals(); i++)\n\t    {\n\t\tsb.Append(nLits[i].getAtomicSentence());\n\t\tif (i != (toProve.getNumberNegativeLiterals() - 1))\n\t\t{\n\t\t    sb.Append(\" AND \");\n\t\t}\n\t    }\n\t    if (toProve.getNumberNegativeLiterals() > 0)\n\t    {\n\t\tsb.Append(\" => \");\n\t    }\n\t    sb.Append(toProve.getPositiveLiterals()[0]);\n\t    return sb.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Current Goal \" + currentGoal.getAtomicSentence().ToString()\n\t\t    + \", \" + bindings;\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepChainCancellation.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepChainCancellation : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Chain cancellation = null;\n\tprivate Chain cancellationOf = null;\n\tprivate Dictionary<Variable, Term> subst = null;\n\n\tpublic ProofStepChainCancellation(Chain cancellation, Chain cancellationOf,\n\t\tDictionary<Variable, Term> subst)\n\t{\n\t    this.cancellation = cancellation;\n\t    this.cancellationOf = cancellationOf;\n\t    this.subst = subst;\n\t    this.predecessors.Add(cancellationOf.getProofStep());\n\t}\n\t\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return cancellation.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Cancellation: \" + cancellationOf.getProofStep().getStepNumber()\n\t\t    + \" \" + subst;\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepChainContrapositive.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepChainContrapositive : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Chain contrapositive = null;\n\tprivate Chain contrapositiveOf = null;\n\n\tpublic ProofStepChainContrapositive(Chain contrapositive,\n\t\tChain contrapositiveOf)\n\t{\n\t    this.contrapositive = contrapositive;\n\t    this.contrapositiveOf = contrapositiveOf;\n\t    this.predecessors.Add(contrapositiveOf.getProofStep());\n\t}\n\t\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return contrapositive.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Contrapositive: \"\n\t\t    + contrapositiveOf.getProofStep().getStepNumber();\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepChainDropped.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepChainDropped : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Chain dropped = null;\n\tprivate Chain droppedOff = null;\n\n\tpublic ProofStepChainDropped(Chain dropped, Chain droppedOff)\n\t{\n\t    this.dropped = dropped;\n\t    this.droppedOff = droppedOff;\n\t    this.predecessors.Add(droppedOff.getProofStep());\n\t}\n\t\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return dropped.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Dropped: \" + droppedOff.getProofStep().getStepNumber();\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepChainFromClause.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepChainFromClause : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Chain chain = null;\n\tprivate Clause fromClause = null;\n\n\tpublic ProofStepChainFromClause(Chain chain, Clause fromClause)\n\t{\n\t    this.chain = chain;\n\t    this.fromClause = fromClause;\n\t    this.predecessors.Add(fromClause.getProofStep());\n\t}\n\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\t\n\tpublic override String getProof()\n\t{\n\t    return chain.ToString();\n\t}\n\t\n\tpublic override String getJustification()\n\t{\n\t    return \"Chain from Clause: \"\n\t\t\t    + fromClause.getProofStep().getStepNumber();\n\t}\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepChainReduction.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepChainReduction : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Chain reduction = null;\n\tprivate Chain nearParent, farParent = null;\n\tprivate Dictionary<Variable, Term> subst = null;\n\n\tpublic ProofStepChainReduction(Chain reduction, Chain nearParent,\n\t\tChain farParent, Dictionary<Variable, Term> subst)\n\t{\n\t    this.reduction = reduction;\n\t    this.nearParent = nearParent;\n\t    this.farParent = farParent;\n\t    this.subst = subst;\n\t    this.predecessors.Add(farParent.getProofStep());\n\t    this.predecessors.Add(nearParent.getProofStep());\n\t}\n\t\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return reduction.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Reduction: \" + nearParent.getProofStep().getStepNumber() + \",\"\n\t\t    + farParent.getProofStep().getStepNumber() + \" \" + subst;\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepClauseBinaryResolvent.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepClauseBinaryResolvent : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Clause resolvent = null;\n\tprivate Literal posLiteral = null;\n\tprivate Literal negLiteral = null;\n\tprivate Clause parent1, parent2 = null;\n\tprivate Dictionary<Variable, Term> subst = new Dictionary<Variable, Term>();\n\tprivate Dictionary<Variable, Term> renameSubst = new Dictionary<Variable, Term>();\n        private Clause c;\n        private Clause clause;\n        private Clause othC;\n        private Dictionary<Variable, Term> copyRBindings;\n        private Dictionary<Variable, Term> renameSubstitituon;\n\n        public ProofStepClauseBinaryResolvent(Clause resolvent, Literal pl,\n\t\t\tLiteral nl, Clause parent1, Clause parent2,\n\t\t\tDictionary<Variable, Term> subst, Dictionary<Variable, Term> renameSubst)\n\t{\n\t    this.resolvent = resolvent;\n\t    this.posLiteral = pl;\n\t    this.negLiteral = nl;\n\t    this.parent1 = parent1;\n\t    this.parent2 = parent2;\n\n\t    foreach (Variable key in subst.Keys)\n\t    {\n\t\tthis.subst.Add(key, subst[key]);\n\t    }\n\n\t    foreach (Variable key in renameSubst.Keys)\n\t    {\n\t\tthis.renameSubst.Add(key, renameSubst[key]);\n\t    }\n\n\t    this.predecessors.Add(parent1.getProofStep());\n\t    this.predecessors.Add(parent2.getProofStep());\n\t}\n\n        public ProofStepClauseBinaryResolvent(Clause c, Clause clause, Clause othC, Dictionary<Variable, Term> copyRBindings, Dictionary<Variable, Term> renameSubstitituon)\n        {\n            this.c = c;\n            this.clause = clause;\n            this.othC = othC;\n            this.copyRBindings = copyRBindings;\n            this.renameSubstitituon = renameSubstitituon;\n        }\n\n        // START-ProofStep\n\n        public override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return resolvent.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    int lowStep = parent1.getProofStep().getStepNumber();\n\t    int highStep = parent2.getProofStep().getStepNumber();\n\n\t    if (lowStep > highStep)\n\t    {\n\t\tlowStep = highStep;\n\t\thighStep = parent1.getProofStep().getStepNumber();\n\t    }\n\n\t    return \"Resolution: \" + lowStep + \", \" + highStep + \"  [\" + posLiteral\n\t\t\t    + \", \" + negLiteral + \"], subst=\" + subst + \", renaming=\"\n\t\t\t    + renameSubst;\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepClauseClausifySentence.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepClauseClausifySentence : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Clause clausified = null;\n\n\tpublic ProofStepClauseClausifySentence(Clause clausified,\n\t\t\tSentence origSentence)\n\t{\n\t    this.clausified = clausified;\n\t    this.predecessors.Add(new ProofStepPremise(origSentence));\n\t}\n\t\n\t// START-ProofStep\n\t\t\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return clausified.ToString();\n\t}\n\t\n\tpublic override String getJustification()\n\t{\n\t    return \"Clausified \" + predecessors[0].getStepNumber();\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepClauseDemodulation.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepClauseDemodulation : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Clause demodulated = null;\n\tprivate Clause origClause = null;\n\tprivate TermEquality assertion = null;\n\n\tpublic ProofStepClauseDemodulation(Clause demodulated, Clause origClause,\n\t\t\tTermEquality assertion)\n\t{\n\t    this.demodulated = demodulated;\n\t    this.origClause = origClause;\n\t    this.assertion = assertion;\n\t    this.predecessors.Add(origClause.getProofStep());\n\t}\n\n\t// START-ProofStep\n\t\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return demodulated.ToString();\n\t}\n\t\n\tpublic override String getJustification()\n\t{\n\t    return \"Demodulation: \" + origClause.getProofStep().getStepNumber()\n\t\t\t    + \", [\" + assertion + \"]\";\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepClauseFactor.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepClauseFactor : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Clause factor = null;\n\tprivate Clause factorOf = null;\n\tprivate Literal lx = null;\n\tprivate Literal ly = null;\n\tprivate Dictionary<Variable, Term> subst = new Dictionary<Variable, Term>();\n\tprivate Dictionary<Variable, Term> renameSubst = new Dictionary<Variable, Term>();\n\n\tpublic ProofStepClauseFactor(Clause factor, Clause factorOf, Literal lx,\n\t\t\tLiteral ly, Dictionary<Variable, Term> subst,\n\t\t\tDictionary<Variable, Term> renameSubst)\n\t{\n\t    this.factor = factor;\n\t    this.factorOf = factorOf;\n\t    this.lx = lx;\n\t    this.ly = ly;\n\t    \n\t    foreach (Variable key in subst.Keys)\n\t    {\n\t\tthis.subst.Add(key, subst[key]);\n\t    }\n\n\t    foreach (Variable key in renameSubst.Keys)\n\t    {\n\t\tthis.renameSubst.Add(key, renameSubst[key]);\n\t    }\n\n\t    this.predecessors.Add(factorOf.getProofStep());\n\t}\n\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return factor.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Factor of \" + factorOf.getProofStep().getStepNumber() + \"  [\"\n\t\t\t    + lx + \", \" + ly + \"], subst=\" + subst + \", renaming=\"\n\t\t\t    + renameSubst;\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepClauseParamodulation.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepClauseParamodulation : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Clause paramodulated = null;\n\tprivate Clause topClause = null;\n\tprivate Clause equalityClause = null;\n\tprivate TermEquality assertion = null;\n\n\tpublic ProofStepClauseParamodulation(Clause paramodulated,\n\t\tClause topClause, Clause equalityClause, TermEquality assertion)\n\t{\n\t    this.paramodulated = paramodulated;\n\t    this.topClause = topClause;\n\t    this.equalityClause = equalityClause;\n\t    this.assertion = assertion;\n\t    this.predecessors.Add(topClause.getProofStep());\n\t    this.predecessors.Add(equalityClause.getProofStep());\n\t}\n\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return paramodulated.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Paramodulation: \" + topClause.getProofStep().getStepNumber()\n\t\t    + \", \" + equalityClause.getProofStep().getStepNumber() + \", [\"\n\t\t    + assertion + \"]\";\n\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepFoChAlreadyAFact.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepFoChAlreadyAFact : AbstractProofStep\n    {\n\tprivate readonly List<ProofStep> _noPredecessors = new List<ProofStep>();\n\tprivate Literal fact = null;\n\n\tpublic ProofStepFoChAlreadyAFact(Literal fact)\n\t{\n\t    this.fact = fact;\n\t}\n\t\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(_noPredecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return fact.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Already a known fact in the KB.\";\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepFoChAssertFact.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepFoChAssertFact : AbstractProofStep\n    {\t\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Clause implication = null;\n\tprivate Literal fact = null;\n\tprivate Dictionary<Variable, Term> bindings = null;\n\n\tpublic ProofStepFoChAssertFact(Clause implication, Literal fact,\n\t\tDictionary<Variable, Term> bindings, ProofStep predecessor)\n\t{\n\t    this.implication = implication;\n\t    this.fact = fact;\n\t    this.bindings = bindings;\n\t    if (null != predecessor)\n\t    {\n\t\tpredecessors.Add(predecessor);\n\t    }\n\t}\n\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    StringBuilder sb = new StringBuilder();\n\t    List<Literal> nLits = implication.getNegativeLiterals();\n\t    for (int i = 0; i < implication.getNumberNegativeLiterals(); i++)\n\t    {\n\t\tsb.Append(nLits[i].getAtomicSentence());\n\t\tif (i != (implication.getNumberNegativeLiterals() - 1))\n\t\t{\n\t\t    sb.Append(\" AND \");\n\t\t}\n\t    }\n\t    sb.Append(\" => \");\n\t    sb.Append(implication.getPositiveLiterals()[0]);\n\t    return sb.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Assert fact \" + fact.ToString() + \", \" + bindings;\n\t}\n\t\n\t// END-ProofStep\t\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepGoal.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepGoal : AbstractProofStep\n    {\n\tprivate static readonly List<ProofStep> _noPredecessors = new List<ProofStep>();\n\n\tprivate Object proof = \"\";\n\n\tpublic ProofStepGoal(Object proof)\n\t{\n\t    this.proof = proof;\n\t}\n\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(_noPredecessors).ToList<ProofStep>();\n\t}\n\t\n\tpublic override String getProof()\n\t{\n\t    return proof.ToString();\n\t}\n\t\n\tpublic override String getJustification()\n\t{\n\t    return \"Goal\";\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepPremise.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepPremise : AbstractProofStep\n    {\n\tprivate static readonly List<ProofStep> _noPredecessors = new List<ProofStep>();\n\n\tprivate Object proof = \"\";\n\n\tpublic ProofStepPremise(Object proof)\n\t{\n\t    this.proof = proof;\n\t}\n\n\t// START-ProofStep\n\t\t\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(_noPredecessors).ToList<ProofStep>();\n\t}\n\t\t\n\tpublic override String getProof()\n\t{\n\t    return proof.ToString();\n\t}\n\t\n\tpublic override String getJustification()\n\t{\n\t    return \"Premise\";\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/proof/ProofStepRenaming.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\n\nnamespace aima.core.logic.fol.inference.proof\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ProofStepRenaming : AbstractProofStep\n    {\n\tprivate List<ProofStep> predecessors = new List<ProofStep>();\n\tprivate Object proof = \"\";\n\n\tpublic ProofStepRenaming(Object proof, ProofStep predecessor)\n\t{\n\t    this.proof = proof;\n\t    this.predecessors.Add(predecessor);\n\t}\n\n\t// START-ProofStep\n\n\tpublic override List<ProofStep> getPredecessorSteps()\n\t{\n\t    return new ReadOnlyCollection<ProofStep>(predecessors).ToList<ProofStep>();\n\t}\n\n\tpublic override String getProof()\n\t{\n\t    return proof.ToString();\n\t}\n\n\tpublic override String getJustification()\n\t{\n\t    return \"Renaming of \" + predecessors[0].getStepNumber();\n\t}\n\n\t// END-ProofStep\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/trace/FOLModelEliminationTracer.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.logic.fol.inference.trace\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface FOLModelEliminationTracer\n    {\n\tvoid reset();\n\n\tvoid increment(int depth, int noFarParents);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/inference/trace/FOLTFMResolutiontracer.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.inference;\nusing aima.core.logic.fol.kb.data;\n\nnamespace aima.core.logic.fol.inference.trace\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface FOLTFMResolutionTracer\n    {\n\tvoid stepStartWhile(HashSet<Clause> clauses, int totalNoClauses,\n\t\t\tint totalNoNewCandidateClauses);\n\n\tvoid stepOuterFor(Clause i);\n\n\tvoid stepInnerFor(Clause i, Clause j);\n\n\tvoid stepResolved(Clause iFactor, Clause jFactor, HashSet<Clause> resolvents);\n\n\tvoid stepFinished(HashSet<Clause> clauses, InferenceResult result);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/kb/FOLKnowledgeBase.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Linq;\nusing aima.core.logic.fol;\nusing aima.core.logic.fol.inference;\nusing aima.core.logic.fol.kb.data;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.parsing.ast;\nusing aima.core.logic.fol.domain;\nusing aima.core.logic.fol.inference.proof;\n\nnamespace aima.core.logic.fol.kb\n{\n    /**\n     * A First Order Logic (FOL) Knowledge Base.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class FOLKnowledgeBase\n    {\n\tprivate FOLParser parser;\n\tprivate InferenceProcedure inferenceProcedure;\n\tprivate Unifier unifier;\n\tprivate SubstVisitor substVisitor;\n\tprivate VariableCollector variableCollector;\n\tprivate StandardizeApart _standardizeApart;\n\tprivate CNFConverter cnfConverter;\n\t\n\t// Persistent data structures\t\n\t// Keeps track of the Sentences in their original form as added to the\n\t// Knowledge base.\n\tprivate List<Sentence> originalSentences = new List<Sentence>();\n\t// The KB in clause form\n\tprivate List<Clause> clauses = new List<Clause>();\n\t// Keep track of all of the definite clauses in the database\n\t// along with those that represent implications.\n\tprivate List<Clause> allDefiniteClauses = new List<Clause>();\n\tprivate List<Clause> implicationDefiniteClauses = new List<Clause>();\n\t// All the facts in the KB indexed by Atomic Sentence name (Note: pg. 279)\n\tprivate Dictionary<String, List<Literal>> indexFacts = new Dictionary<String, List<Literal>>();\n\t// Keep track of indexical keys for uniquely standardizing apart sentences\n\tprivate StandardizeApartIndexical variableIndexical = StandardizeApartIndexicalFactory\n\t\t.newStandardizeApartIndexical('v');\n\tprivate StandardizeApartIndexical queryIndexical = StandardizeApartIndexicalFactory\n\t\t.newStandardizeApartIndexical('q');\n   \n\t\n\t// PUBLIC METHODS\n\t\n\tpublic FOLKnowledgeBase(FOLDomain domain) : this(domain, new FOLOTTERLikeTheoremProver())\n\t{\n\t    // Default to Full Resolution if not set.\n\n\t}\n\n\tpublic FOLKnowledgeBase(FOLDomain domain,\n\t\tInferenceProcedure inferenceProcedure) : this(domain, inferenceProcedure, new Unifier())\n\t{\n\n\t}\n\n\tpublic FOLKnowledgeBase(FOLDomain domain,\n\t\tInferenceProcedure inferenceProcedure, Unifier unifier)\n\t{\n\t    this.parser = new FOLParser(new FOLDomain(domain));\n\t    this.inferenceProcedure = inferenceProcedure;\n\t    this.unifier = unifier;\n\t    //\n\t    this.substVisitor = new SubstVisitor();\n\t    this.variableCollector = new VariableCollector();\n\t    this._standardizeApart = new StandardizeApart(variableCollector,\n\t\t    substVisitor);\n\t    this.cnfConverter = new CNFConverter(parser);\n\t}\n\n\tpublic void clear()\n\t{\n\t    this.originalSentences.Clear();\n\t    this.clauses.Clear();\n\t    this.allDefiniteClauses.Clear();\n\t    this.implicationDefiniteClauses.Clear();\n\t    this.indexFacts.Clear();\n\t}\n\n\tpublic InferenceProcedure getInferenceProcedure()\n\t{\n\t    return inferenceProcedure;\n\t}\n\n\tpublic void setInferenceProcedure(InferenceProcedure inferenceProcedure)\n\t{\n\t    if (null != inferenceProcedure)\n\t    {\n\t\tthis.inferenceProcedure = inferenceProcedure;\n\t    }\n\t}\n\n\tpublic Sentence tell(String aSentence)\n\t{\n\t    Sentence s = parser.parse(aSentence);\n\t    tell(s);\n\t    return s;\n\t}\n\n\tpublic void tell(List<Sentence> sentences)\n\t{\n\t    foreach (Sentence s in sentences)\n\t    {\n\t\ttell(s);\n\t    }\n\t}\n\n\tpublic void tell(Sentence aSentence)\n\t{\n\t    store(aSentence);\n\t}\n\n\t/**\n\t* \n\t* @param aQuerySentence\n\t* @return an InferenceResult.\n\t*/\n\tpublic InferenceResult ask(String aQuerySentence)\n\t{\n\t    return ask(parser.parse(aQuerySentence));\n\t}\n\n\tpublic InferenceResult ask(Sentence aQuery)\n\t{\n\t    // Want to standardize apart the query to ensure\n\t    // it does not clash with any of the sentences\n\t    // in the database\n\t    StandardizeApartResult saResult = _standardizeApart.standardizeApart(\n\t\t    aQuery, queryIndexical);\n\n\t    // Need to map the result variables (as they are standardized apart)\n\t    // to the original queries variables so that the caller can easily\n\t    // understand and use the returned set of substitutions\n\t    InferenceResult infResult = getInferenceProcedure().ask(this,\n\t\t    saResult.getStandardized());\n\t    List<Proof> proofs = infResult.getProofs();\n\t    foreach (Proof p in proofs)\n\t    {\n\t\tDictionary<Variable, Term> im = p.getAnswerBindings();\n\t\tDictionary<Variable, Term> em = new Dictionary<Variable, Term>();\n\t\tforeach (Variable rev in saResult.getReverseSubstitution().Keys)\n\t\t{\n\t\t    em.Add((Variable)saResult.getReverseSubstitution()[rev],\n\t\t\t    im[rev]);\n\t\t}\n\t\tp.replaceAnswerBindings(em);\n\t    }\n\t    return infResult;\n\t}\n\n\tpublic int getNumberFacts()\n\t{\n\t    return allDefiniteClauses.Count - implicationDefiniteClauses.Count;\n\t}\n\n\tpublic int getNumberRules()\n\t{\n\t    return clauses.Count - getNumberFacts();\n\t}\n\n\tpublic List<Sentence> getOriginalSentences()\n\t{\n\t    return new System.Collections.ObjectModel.ReadOnlyCollection<Sentence>(originalSentences).ToList<Sentence>();\n\t}\n\n\tpublic List<Clause> getAllDefiniteClauses()\n\t{\n\t    return new System.Collections.ObjectModel.ReadOnlyCollection<Clause>(allDefiniteClauses).ToList<Clause>();\n\t}\n\n\tpublic List<Clause> getAllDefiniteClauseImplications()\n\t{\n\t    return new System.Collections.ObjectModel.ReadOnlyCollection<Clause>(implicationDefiniteClauses).ToList<Clause>();\n\t}\n\n\tpublic List<Clause> getAllClauses()\n\t{\n\t    return new System.Collections.ObjectModel.ReadOnlyCollection<Clause>(clauses).ToList<Clause>();\n\t}\n\n\t// Note: pg 278, FETCH(q) concept.\n\tpublic /* lock */ List<Dictionary<Variable, Term>> fetch(Literal l)\n\t{\n\t    // Get all of the substitutions in the KB that p unifies with\n\t    List<Dictionary<Variable, Term>> allUnifiers = new List<Dictionary<Variable, Term>>();\n\n\t    List<Literal> matchingFacts = fetchMatchingFacts(l);\n\t    if (null != matchingFacts)\n\t    {\n\t\tforeach (Literal fact in matchingFacts)\n\t\t{\n\t\t    Dictionary<Variable, Term> substitution = unifier.unify(l\n\t\t\t    .getAtomicSentence(), fact.getAtomicSentence());\n\t\t    if (null != substitution)\n\t\t    {\n\t\t\tallUnifiers.Add(substitution);\n\t\t    }\n\t\t}\n\t    }\n\t    return allUnifiers;\n\t}\n\n\t// Note: To support FOL-FC-Ask\n\tpublic List<Dictionary<Variable, Term>> fetch(List<Literal> literals)\n\t{\n\t    List<Dictionary<Variable, Term>> possibleSubstitutions = new List<Dictionary<Variable, Term>>();\n\n\t    if (literals.Count > 0)\n\t    {\n\t\tLiteral first = literals[0];\n\t\tList<Literal> rest = literals.Skip(1).ToList<Literal>();\n\n\t\trecursiveFetch(new Dictionary<Variable, Term>(), first, rest,\n\t\t\tpossibleSubstitutions);\n\t    }\n\t    return possibleSubstitutions;\n\t}\n\n\tpublic Dictionary<Variable, Term> unify(FOLNode x, FOLNode y)\n\t{\n\t    return unifier.unify(x, y);\n\t}\n\n\tpublic Sentence subst(Dictionary<Variable, Term> theta, Sentence aSentence)\n\t{\n\t    return substVisitor.subst(theta, aSentence);\n\t}\n\n\tpublic Literal subst(Dictionary<Variable, Term> theta, Literal l)\n\t{\n\t    return substVisitor.subst(theta, l);\n\t}\n\n\tpublic Term subst(Dictionary<Variable, Term> theta, Term aTerm)\n\t{\n\t    return substVisitor.subst(theta, aTerm);\n\t}\n\n\t// Note: see page 277.\n\tpublic Sentence standardizeApart(Sentence aSentence)\n\t{\n\t    return _standardizeApart.standardizeApart(aSentence, variableIndexical)\n\t\t    .getStandardized();\n\t}\n\n\tpublic Clause standardizeApart(Clause aClause)\n\t{\n\t    return _standardizeApart.standardizeApart(aClause, variableIndexical);\n\t}\n\n\tpublic Chain standardizeApart(Chain aChain)\n\t{\n\t    return _standardizeApart.standardizeApart(aChain, variableIndexical);\n\t}\n\n\tpublic List<Variable> collectAllVariables(Sentence aSentence)\n\t{\n\t    return variableCollector.collectAllVariables(aSentence);\n\t}\n\n\tpublic CNF convertToCNF(Sentence aSentence)\n\t{\n\t    return cnfConverter.convertToCNF(aSentence);\n\t}\n\n\tpublic List<Clause> convertToClauses(Sentence aSentence)\n\t{\n\t    CNF cnf = cnfConverter.convertToCNF(aSentence);\n\n\t    return new List<Clause>(cnf.getConjunctionOfClauses());\n\t}\n\n\tpublic Literal createAnswerLiteral(Sentence forQuery)\n\t{\n\t    String alName = parser.getFOLDomain().addAnswerLiteral();\n\t    List<Term> terms = new List<Term>();\n\n\t    List<Variable> vars = variableCollector.collectAllVariables(forQuery);\n\t    foreach (Variable v in vars)\n\t    {\n\t\t// Ensure copies of the variables are used.\n\t\tterms.Add((Term)v.copy());\n\t    }\n\t    return new Literal(new Predicate(alName, terms));\n\t}\n\n\t// Note: see pg. 281\n\tpublic bool isRenaming(Literal l)\n\t{\n\t    List<Literal> possibleMatches = fetchMatchingFacts(l);\n\t    if (null != possibleMatches)\n\t    {\n\t\treturn isRenaming(l, possibleMatches);\n\t    }\n\t    return false;\n\t}\n\n\t// Note: see pg. 281\n\tpublic bool isRenaming(Literal l, List<Literal> possibleMatches)\n\t{\n\n\t    foreach (Literal q in possibleMatches)\n\t    {\n\t\tif (l.isPositiveLiteral() != q.isPositiveLiteral())\n\t\t{\n\t\t    continue;\n\t\t}\n\t\tDictionary<Variable, Term> subst = unifier.unify(l.getAtomicSentence(), q\n\t\t\t.getAtomicSentence());\n\t\tif (null != subst)\n\t\t{\n\t\t    int cntVarTerms = 0;\n\t\t    foreach (Term t in subst.Values)\n\t\t    {\n\t\t\tif (t is Variable)\n\t\t\t{\n\t\t\t    cntVarTerms++;\n\t\t\t}\n\t\t    }\n\t\t    // If all the substitutions, even if none, map to Variables\n\t\t    // then this is a renaming\n\t\t    if (subst.Count == cntVarTerms)\n\t\t    {\n\t\t\treturn true;\n\t\t    }\n\t\t}\n\t    }\n\t    return false;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    StringBuilder sb = new StringBuilder();\n\t    foreach (Sentence s in originalSentences)\n\t    {\n\t\tsb.Append(s.ToString());\n\t\tsb.Append(\"\\n\");\n\t    }\n\t    return sb.ToString();\n\t}\n\n\t\n\t// PROTECTED METHODS\n\t\n\tprotected FOLParser getParser()\n\t{\n\t    return parser;\n\t}\n\n\t\n\t// PRIVATE METHODS\n\t\n\t// Note: pg 278, STORE(s) concept.\n\tprivate /*lock*/ void store(Sentence aSentence)\n\t{\n\t    originalSentences.Add(aSentence);\n\n\t    // Convert the sentence to CNF\n\t    CNF cnfOfOrig = cnfConverter.convertToCNF(aSentence);\n\t    List<Clause> conjunctionOfClauses = cnfOfOrig.getConjunctionOfClauses();\n\t    foreach (Clause c in conjunctionOfClauses)\n\t    {\n\t\tc.setProofStep(new ProofStepClauseClausifySentence(c, aSentence));\n\t\tif (c.isEmpty())\n\t\t{\n\t\t    // This should not happen, if so the user\n\t\t    // is trying to add an unsatisfiable sentence\n\t\t    // to the KB.\n\t\t    throw new ArgumentException(\n\t\t\t    \"Attempted to add unsatisfiable sentence to KB, orig=[\"\n\t\t\t\t    + aSentence + \"] CNF=\" + cnfOfOrig);\n\t\t}\n\n\t\t// Ensure all clauses added to the KB are Standardized Apart.\n\t\tClause c2 = _standardizeApart.standardizeApart(c, variableIndexical);\n\n\t\t// Will make all clauses immutable\n\t\t// so that they cannot be modified externally.\n\t\tc2.setImmutable();\n\t\tif (!clauses.Contains(c2))\n\t\t{\n\t\t    clauses.Add(c2);\n\t\t    // If added keep track of special types of\n\t\t    // clauses, as useful for query purposes\n\t\t    if (c2.isDefiniteClause())\n\t\t    {\n\t\t\tallDefiniteClauses.Add(c2);\n\t\t    }\n\t\t    if (c2.isImplicationDefiniteClause())\n\t\t    {\n\t\t\timplicationDefiniteClauses.Add(c2);\n\t\t    }\n\t\t    if (c2.isUnitClause())\n\t\t    {\n\t\t\tindexFact(c2.getLiterals().First<Literal>());\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\t// Only if it is a unit clause does it get indexed as a fact\n\t// see pg. 279 for general idea.\n\tprivate void indexFact(Literal fact)\n\t{\n\t    String factKey = getFactKey(fact);\n\t    if (!indexFacts.ContainsKey(factKey))\n\t    {\n\t\tindexFacts.Add(factKey, new List<Literal>());\n\t    }\n\t    indexFacts[factKey].Add(fact);\n\t}\n\n\tprivate void recursiveFetch(Dictionary<Variable, Term> theta, Literal l,\n\t\tList<Literal> remainingLiterals,\n\t\tList<Dictionary<Variable, Term>> possibleSubstitutions)\n\t{\n\n\t    // Find all substitutions for current predicate based on the\n\t    // substitutions of prior predicates in the list (i.e. SUBST with\n\t    // theta).\n\t    List<Dictionary<Variable, Term>> pSubsts = fetch(subst(theta, l));\n\n\t    // No substitutions, therefore cannot continue\n\t    if (null == pSubsts)\n\t    {\n\t\treturn;\n\t    }\n\n\t    foreach (Dictionary<Variable, Term> psubst in pSubsts)\n\t    {\n\t\t// Ensure all prior substitution information is maintained\n\t\t// along the chain of predicates (i.e. for shared variables\n\t\t// across the predicates).\n\t\tforeach (Variable key in theta.Keys)\n\t\t{\n\t\t    psubst.Add(key, theta[key]);\n\t\t}\n\t\tif (remainingLiterals.Count == 0)\n\t\t{\n\t\t    // This means I am at the end of the chain of predicates\n\t\t    // and have found a valid substitution.\n\t\t    possibleSubstitutions.Add(psubst);\n\t\t}\n\t\telse\n\t\t{\n\t\t    // Need to move to the next link in the chain of substitutions\n\t\t    Literal first = remainingLiterals[0];\n\t\t    List<Literal> rest = remainingLiterals.Skip(1).ToList<Literal>();\n\n\t\t    recursiveFetch(psubst, first, rest, possibleSubstitutions);\n\t\t}\n\t    }\n\t}\n\n\tprivate List<Literal> fetchMatchingFacts(Literal l)\n\t{\n\t    if (!indexFacts.ContainsKey(getFactKey(l)))\n\t    {\n\t\treturn null;\n\t    }\n\t    return indexFacts[getFactKey(l)];\n\t}\n\n\tprivate String getFactKey(Literal l)\n\t{\n\t    StringBuilder key = new StringBuilder();\n\t    if (l.isPositiveLiteral())\n\t    {\n\t\tkey.Append(\"+\");\n\t    }\n\t    else\n\t    {\n\t\tkey.Append(\"-\");\n\t    }\n\t    key.Append(l.getAtomicSentence().getSymbolicName());\n\t    return key.ToString();\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/kb/FOLKnowledgeBaseFactory.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.domain;\nusing aima.core.logic.fol.inference;\n\nnamespace aima.core.logic.fol.kb\n{\n\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public class FOLKnowledgeBaseFactory\n    {\n\tpublic static FOLKnowledgeBase createKingsKnowledgeBase(\n\t\tInferenceProcedure infp)\n\t{\n\t    FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory.kingsDomain(),\n\t\t    infp);\n\t    kb.tell(\"((King(x) AND Greedy(x)) => Evil(x))\");\n\t    kb.tell(\"King(John)\");\n\t    kb.tell(\"King(Richard)\");\n\t    kb.tell(\"Greedy(John)\");\n\t    return kb;\n\t}\n\n\tpublic static FOLKnowledgeBase createWeaponsKnowledgeBase(\n\t\tInferenceProcedure infp)\n\t{\n\t    FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory\n\t\t    .weaponsDomain(), infp);\n\t    kb\n\t\t    .tell(\"( (((American(x) AND Weapon(y)) AND Sells(x,y,z)) AND Hostile(z)) => Criminal(x))\");\n\t    kb.tell(\" Owns(Nono, M1)\");\n\t    kb.tell(\" Missile(M1)\");\n\t    kb.tell(\"((Missile(x) AND Owns(Nono,x)) => Sells(West,x,Nono))\");\n\t    kb.tell(\"(Missile(x) => Weapon(x))\");\n\t    kb.tell(\"(Enemy(x,America) => Hostile(x))\");\n\t    kb.tell(\"American(West)\");\n\t    kb.tell(\"Enemy(Nono,America)\");\n\t    return kb;\n\t}\n\n\tpublic static FOLKnowledgeBase createLovesAnimalKnowledgeBase(\n\t\tInferenceProcedure infp)\n\t{\n\t    FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory\n\t\t    .lovesAnimalDomain(), infp);\n\n\t    kb\n\t\t    .tell(\"FORALL x (FORALL y (Animal(y) => Loves(x, y)) => EXISTS y Loves(y, x))\");\n\t    kb\n\t\t    .tell(\"FORALL x (EXISTS y (Animal(y) AND Kills(x, y)) => FORALL z NOT(Loves(z, x)))\");\n\t    kb.tell(\"FORALL x (Animal(x) => Loves(Jack, x))\");\n\t    kb.tell(\"(Kills(Jack, Tuna) OR Kills(Curiosity, Tuna))\");\n\t    kb.tell(\"Cat(Tuna)\");\n\t    kb.tell(\"FORALL x (Cat(x) => Animal(x))\");\n\t    return kb;\n\t}\n\n\tpublic static FOLKnowledgeBase createRingOfThievesKnowledgeBase(\n\t\tInferenceProcedure infp)\n\t{\n\t    FOLKnowledgeBase kb = new FOLKnowledgeBase(DomainFactory\n\t\t    .ringOfThievesDomain(), infp);\n\n\t    // s(x) => ~c(x) One who skis never gets caught\n\t    kb.tell(\"(Skis(x) => NOT(Caught(x)))\");\n\t    // c(x) => ~s(x) Those who are caught don't ever ski\n\t    kb.tell(\"(Caught(x) => NOT(Skis(x)))\");\n\t    // p(x,y) & c(y) => s(x) Jailbird parents have skiing kids\n\t    kb.tell(\"((Parent(x,y) AND Caught(y)) => Skis(x))\");\n\t    // s(x) & f(x,y) => s(y) All friends ski together\n\t    kb.tell(\"(Skis(x) AND Friend(x,y) => Skis(y))\");\n\t    // f(x,y) => f(y,x) Friendship is symmetric\n\t    kb.tell(\"(Friend(x,y) => Friend(y,x))\");\n\t    // FACTS\n\t    // 1. { p(Mike,Joe) } Premise\n\t    kb.tell(\"Parent(Mike, Joe)\");\n\t    // 2. { p(Janet,Joe) } Premise\n\t    kb.tell(\"Parent(Janet,Joe)\");\n\t    // 3. { p(Nancy,Mike) } Premise\n\t    kb.tell(\"Parent(Nancy,Mike)\");\n\t    // 4. { p(Ernie,Janet) } Premise\n\t    kb.tell(\"Parent(Ernie,Janet)\");\n\t    // 5. { p(Bert,Nancy) } Premise\n\t    kb.tell(\"Parent(Bert,Nancy)\");\n\t    // 6. { p(Red,Ernie) } Premise\n\t    kb.tell(\"Parent(Red,Ernie)\");\n\t    // 7. { f(Red,Bert) } Premise\n\t    kb.tell(\"Friend(Red,Bert)\");\n\t    // 8. { f(Drew,Nancy) } Premise\n\t    kb.tell(\"Friend(Drew,Nancy)\");\n\t    // 9. { c(Mike) } Premise\n\t    kb.tell(\"Caught(Mike)\");\n\t    // 10. { c(Ernie) } Premise\n\t    kb.tell(\"Caught(Ernie)\");\n\t    return kb;\n\t}\n\n\t// Note: see -\n\t// http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf\n\t// slide 12 for where this test example was taken from.\n\tpublic static FOLKnowledgeBase createABCEqualityKnowledgeBase(\n\t\tInferenceProcedure infp, bool includeEqualityAxioms)\n\t{\n\t    FOLDomain domain = new FOLDomain();\n\t    domain.addConstant(\"A\");\n\t    domain.addConstant(\"B\");\n\t    domain.addConstant(\"C\");\n\n\t    FOLKnowledgeBase kb = new FOLKnowledgeBase(domain, infp);\n\n\t    kb.tell(\"B = A\");\n\t    kb.tell(\"B = C\");\n\n\t    if (includeEqualityAxioms)\n\t    {\n\t\t// Reflexivity Axiom\n\t\tkb.tell(\"x = x\");\n\t\t// Symmetry Axiom\n\t\tkb.tell(\"(x = y => y = x)\");\n\t\t// Transitivity Axiom\n\t\tkb.tell(\"((x = y AND y = z) => x = z)\");\n\t    }\n\t    return kb;\n\t}\n\n\t// Note: see -\n\t// http://logic.stanford.edu/classes/cs157/2008/lectures/lecture15.pdf\n\t// slide 16,17, and 18 for where this test example was taken from.\n\tpublic static FOLKnowledgeBase createABCDEqualityAndSubstitutionKnowledgeBase(\n\t\tInferenceProcedure infp, bool includeEqualityAxioms)\n\t{\n\t    FOLDomain domain = new FOLDomain();\n\t    domain.addConstant(\"A\");\n\t    domain.addConstant(\"B\");\n\t    domain.addConstant(\"C\");\n\t    domain.addConstant(\"D\");\n\t    domain.addPredicate(\"P\");\n\t    domain.addFunction(\"F\");\n\n\t    FOLKnowledgeBase kb = new FOLKnowledgeBase(domain, infp);\n\n\t    kb.tell(\"F(A) = B\");\n\t    kb.tell(\"F(B) = A\");\n\t    kb.tell(\"C = D\");\n\t    kb.tell(\"P(A)\");\n\t    kb.tell(\"P(C)\");\n\n\t    if (includeEqualityAxioms)\n\t    {\n\t\t// Reflexivity Axiom\n\t\tkb.tell(\"x = x\");\n\t\t// Symmetry Axiom\n\t\tkb.tell(\"(x = y => y = x)\");\n\t\t// Transitivity Axiom\n\t\tkb.tell(\"((x = y AND y = z) => x = z)\");\n\t\t// Function F Substitution Axiom\n\t\tkb.tell(\"((x = y AND F(y) = z) => F(x) = z)\");\n\t\t// Predicate P Substitution Axiom\n\t\tkb.tell(\"((x = y AND P(y)) => P(x))\");\n\t    }\n\t    return kb;\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/logic/fol/kb/data/CNF.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Text;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.Linq;\n\nnamespace aima.core.logic.fol.kb.data\n{\n    /**\n     * Conjunctive Normal Form (CNF) : a conjunction of clauses, where each clause\n     * is a disjunction of literals.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class CNF\n    {\n\tprivate List<Clause> conjunctionOfClauses = new List<Clause>();\n\n\tpublic CNF(List<Clause> conjunctionOfClauses)\n\t{\n\t    this.conjunctionOfClauses.AddRange(conjunctionOfClauses);\n\t}\n\n\tpublic int getNumberOfClauses()\n\t{\n\t    return conjunctionOfClauses.Count;\n\t}\n\n\tpublic List<Clause> getConjunctionOfClauses()\n\t{\n\t    return new ReadOnlyCollection<Clause>(conjunctionOfClauses).ToList<Clause>();\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    StringBuilder sb = new StringBuilder();\n\t    for (int i = 0; i < conjunctionOfClauses.Count; i++)\n\t    {\n\t\tif (i > 0)\n\t\t{\n\t\t    sb.Append(\",\");\n\t\t}\n\t\tsb.Append(conjunctionOfClauses[i].ToString());\n\t    }\n\n\t    return sb.ToString();\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/kb/data/Chain.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.inference.proof;\n\nnamespace aima.core.logic.fol.kb.data\n{\n    /**\n     * \n     * A Chain is a sequence of literals (while a clause is a set) - order is\n     * important for a chain.\n     * \n     * @see <a\n     *      href=\"http://logic.stanford.edu/classes/cs157/2008/lectures/lecture13.pdf\"\n     *      >Chain</a>\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class Chain\n    {\n\tprivate static readonly List<Literal> _emptyLiteralsList = new List<Literal>();\n\tprivate List<Literal> literals = new List<Literal>();\n\tprivate ProofStep proofStep = null;\n\n\tpublic Chain()\n\t{\n\t    // i.e. the empty chain\n\t}\n\n\tpublic Chain(List<Literal> literals)\n\t{\n\t    this.literals.AddRange(literals);\n\t}\n\n\tpublic ProofStep getProofStep()\n\t{\n\t    if (null == proofStep)\n\t    {\n\t\t// Assume was a premise\n\t\tproofStep = new ProofStepPremise(this);\n\t    }\n\t    return proofStep;\n\t}\n\n\tpublic void setProofStep(ProofStep proofStep)\n\t{\n\t    this.proofStep = proofStep;\n\t}\n\n\tpublic bool isEmpty()\n\t{\n\t    return literals.Count == 0;\n\t}\n\n\tpublic void addLiteral(Literal literal)\n\t{\n\t    literals.Add(literal);\n\t}\n\n\tpublic Literal getHead()\n\t{\n\t    if (0 == literals.Count)\n\t    {\n\t\treturn null;\n\t    }\n\t    return literals[0];\n\t}\n\n\tpublic List<Literal> getTail()\n\t{\n\t    if (0 == literals.Count)\n\t    {\n\t\treturn _emptyLiteralsList;\n\t    }\n\t    return new ReadOnlyCollection<Literal>(literals.Skip(1).ToList<Literal>()).ToList<Literal>();\n\n\t}\n\n\tpublic int getNumberLiterals()\n\t{\n\t    return literals.Count;\n\t}\n\n\tpublic List<Literal> getLiterals()\n\t{\n\t    return new ReadOnlyCollection<Literal>(literals).ToList<Literal>();\n\t}\n\n\t/**\n\t* A contrapositive of a chain is a permutation in which a different literal\n\t* is placed at the front. The contrapositives of a chain are logically\n\t* equivalent to the original chain.\n\t* \n\t* @return a list of contrapositives for this chain.\n\t*/\n\tpublic List<Chain> getContrapositives()\n\t{\n\t    List<Chain> contrapositives = new List<Chain>();\n\t    List<Literal> lits = new List<Literal>();\n\n\t    for (int i = 1; i < literals.Count; i++)\n\t    {\n\t\tlits.Clear();\n\t\tlits.Add(literals[i]);\n\t\tlits.AddRange(literals.Take(i));\n\t\tlits.AddRange(literals.GetRange(i + 1, literals.Count));\n\t\tChain cont = new Chain(lits);\n\t\tcont.setProofStep(new ProofStepChainContrapositive(cont, this));\n\t\tcontrapositives.Add(cont);\n\t    }\n\n\t    return contrapositives;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    StringBuilder sb = new StringBuilder();\n\t    sb.Append(\"<\");\n\n\t    for (int i = 0; i < literals.Count; i++)\n\t    {\n\t\tif (i > 0)\n\t\t{\n\t\t    sb.Append(\",\");\n\t\t}\n\t\tsb.Append(literals[i].ToString());\n\t    }\n\n\t    sb.Append(\">\");\n\n\t    return sb.ToString();\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/kb/data/Clause.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Collections.ObjectModel;\nusing System.Linq;\nusing aima.core.logic.fol;\nusing aima.core.logic.fol.inference.proof;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.parsing.ast;\nusing aima.core.util;\n\nnamespace aima.core.logic.fol.kb.data\n{\n    /**\n     * A Clause: A disjunction of literals.\n     * \n     * \n     * @author Ciaran O'Reilly\n     * @author Tobias Barth\n     * \n     */\n    public class Clause\n    {\n\tprivate static StandardizeApartIndexical _saIndexical = StandardizeApartIndexicalFactory\n\t       .newStandardizeApartIndexical('c');\n\tprivate static Unifier _unifier = new Unifier();\n\tprivate static SubstVisitor _substVisitor = new SubstVisitor();\n\tprivate static VariableCollector _variableCollector = new VariableCollector();\n\tprivate static StandardizeApart _standardizeApart = new StandardizeApart();\n\tprivate static LiteralsSorter _literalSorter = new LiteralsSorter();\n\tprivate List<Literal> literals = new List<Literal>();\n\tprivate List<Literal> positiveLiterals = new List<Literal>();\n\tprivate List<Literal> negativeLiterals = new List<Literal>();\n\tprivate bool immutable = false;\n\tprivate bool saCheckRequired = true;\n\tprivate String equalityIdentity = \"\";\n\tprivate List<Clause> factors = null;\n\tprivate List<Clause> nonTrivialFactors = null;\n\tprivate String stringRep = null;\n\tprivate ProofStep proofStep = null;\n\n\tpublic Clause()\n\t{\n\t    // i.e. the empty clause\n\t}\n\n\tpublic Clause(List<Literal> lits)\n\t{\n\t    this.literals.AddRange(lits);\n\t    foreach (Literal l in literals)\n\t    {\n\t\tif (l.isPositiveLiteral())\n\t\t{\n\t\t    this.positiveLiterals.Add(l);\n\t\t}\n\t\telse\n\t\t{\n\t\t    this.negativeLiterals.Add(l);\n\t\t}\n\t    }\n\t    recalculateIdentity();\n\t}\n\n\tpublic Clause(List<Literal> lits1, List<Literal> lits2)\n\t{\n\t    literals.AddRange(lits1);\n\t    literals.AddRange(lits2);\n\t    foreach (Literal l in literals)\n\t    {\n\t\tif (l.isPositiveLiteral())\n\t\t{\n\t\t    this.positiveLiterals.Add(l);\n\t\t}\n\t\telse\n\t\t{\n\t\t    this.negativeLiterals.Add(l);\n\t\t}\n\t    }\n\t    recalculateIdentity();\n\t}\n\n\tpublic ProofStep getProofStep()\n\t{\n\t    if (null == proofStep)\n\t    {\n\t\t// Assume was a premise\n\t\tproofStep = new ProofStepPremise(this);\n\t    }\n\t    return proofStep;\n\t}\n\n\tpublic void setProofStep(ProofStep proofStep)\n\t{\n\t    this.proofStep = proofStep;\n\t}\n\n\tpublic bool isImmutable()\n\t{\n\t    return immutable;\n\t}\n\n\tpublic void setImmutable()\n\t{\n\t    immutable = true;\n\t}\n\n\tpublic bool isStandardizedApartCheckRequired()\n\t{\n\t    return saCheckRequired;\n\t}\n\n\tpublic void setStandardizedApartCheckNotRequired()\n\t{\n\t    saCheckRequired = false;\n\t}\n\n\tpublic bool isEmpty()\n\t{\n\t    return literals.Count == 0;\n\t}\n\n\tpublic bool isUnitClause()\n\t{\n\t    return literals.Count == 1;\n\t}\n\n\tpublic bool isDefiniteClause()\n\t{\n\t    // A Definite Clause is a disjunction of literals of which exactly 1 is\n\t    // positive.\n\t    return !isEmpty() && positiveLiterals.Count == 1;\n\t}\n\n\tpublic bool isImplicationDefiniteClause()\n\t{\n\t    // An Implication Definite Clause is a disjunction of literals of\n\t    // which exactly 1 is positive and there is 1 or more negative\n\t    // literals.\n\t    return isDefiniteClause() && negativeLiterals.Count >= 1;\n\t}\n\n\tpublic bool isHornClause()\n\t{\n\t    // A Horn clause is a disjunction of literals of which at most one is\n\t    // positive.\n\t    return !isEmpty() && positiveLiterals.Count <= 1;\n\t}\n\n\tpublic bool isTautology()\n\t{\n\n\t    foreach (Literal pl in positiveLiterals)\n\t    {\n\t\t// Literals in a clause must be exact complements\n\t\t// for tautology elimination to apply. Do not\n\t\t// remove non-identical literals just because\n\t\t// they are complements under unification, see pg16:\n\t\t// http://logic.stanford.edu/classes/cs157/2008/notes/chap09.pdf\n\t\tforeach (Literal nl in negativeLiterals)\n\t\t{\n\t\t    if (pl.getAtomicSentence().Equals(nl.getAtomicSentence()))\n\t\t    {\n\t\t\treturn true;\n\t\t    }\n\t\t}\n\t    }\n\n\t    return false;\n\t}\n\n\tpublic void addLiteral(Literal literal)\n\t{\n\t    if (isImmutable())\n\t    {\n\t\tthrow new InvalidOperationException(\n\t\t\t\"Clause is immutable, cannot be updated.\");\n\t    }\n\t    int origSize = literals.Count;\n\t    literals.Add(literal);\n\t    if (literals.Count > origSize)\n\t    {\n\t\tif (literal.isPositiveLiteral())\n\t\t{\n\t\t    positiveLiterals.Add(literal);\n\t\t}\n\t\telse\n\t\t{\n\t\t    negativeLiterals.Add(literal);\n\t\t}\n\t    }\n\t    recalculateIdentity();\n\t}\n\n\tpublic void addPositiveLiteral(AtomicSentence atom)\n\t{\n\t    addLiteral(new Literal(atom));\n\t}\n\n\tpublic void addNegativeLiteral(AtomicSentence atom)\n\t{\n\t    addLiteral(new Literal(atom, true));\n\t}\n\n\tpublic int getNumberLiterals()\n\t{\n\t    return literals.Count;\n\t}\n\n\tpublic int getNumberPositiveLiterals()\n\t{\n\t    return positiveLiterals.Count;\n\t}\n\n\tpublic int getNumberNegativeLiterals()\n\t{\n\t    return negativeLiterals.Count;\n\t}\n\n\tpublic List<Literal> getLiterals()\n\t{\n\t    return new ReadOnlyCollection<Literal>(literals).ToList<Literal>();\n\t}\n\n\tpublic List<Literal> getPositiveLiterals()\n\t{\n\t    return new ReadOnlyCollection<Literal>(positiveLiterals).ToList<Literal>();\n\t}\n\n\tpublic List<Literal> getNegativeLiterals()\n\t{\n\t    return new ReadOnlyCollection<Literal>(negativeLiterals).ToList<Literal>();\n\t}\n\n\tpublic List<Clause> getFactors()\n\t{\n\t    if (null == factors)\n\t    {\n\t\tcalculateFactors(null);\n\t    }\n\t    return new ReadOnlyCollection<Clause>(factors).ToList<Clause>();\n\t}\n\n\tpublic List<Clause> getNonTrivialFactors()\n\t{\n\t    if (null == nonTrivialFactors)\n\t    {\n\t\tcalculateFactors(null);\n\t    }\n\t    return new ReadOnlyCollection<Clause>(nonTrivialFactors).ToList<Clause>();\n\t}\n\n\tpublic bool subsumes(Clause othC)\n\t{\n\t    bool subsumes = false;\n\n\t    // Equality is not subsumption\n\t    if (!(this == othC))\n\t    {\n\t\t// Ensure this has less literals total and that\n\t\t// it is a subset of the other clauses positive and negative counts\n\t\tif (this.getNumberLiterals() < othC.getNumberLiterals()\n\t\t\t&& this.getNumberPositiveLiterals() <= othC\n\t\t\t\t.getNumberPositiveLiterals()\n\t\t\t&& this.getNumberNegativeLiterals() <= othC\n\t\t\t\t.getNumberNegativeLiterals())\n\t\t{\n\n\t\t    Dictionary<String, List<Literal>> thisToTry = collectLikeLiterals(this.literals);\n\t\t    Dictionary<String, List<Literal>> othCToTry = collectLikeLiterals(othC.literals);\n\t\t    // Ensure all like literals from this clause are a subset\n\t\t    // of the other clause.\n\t\t    bool contained = !thisToTry.Keys.Except(othCToTry.Keys).Any();\n\t\t    if (contained)\n\t\t    {\n\t\t\tbool isAPossSubset = true;\n\t\t\t// Ensure that each set of same named literals\n\t\t\t// from this clause is a subset of the other\n\t\t\t// clauses same named literals.\n\t\t\tforeach (String pk in thisToTry.Keys)\n\t\t\t{\n\t\t\t    if (thisToTry[pk].Count > othCToTry[pk].Count)\n\t\t\t    {\n\t\t\t\tisAPossSubset = false;\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t\tif (isAPossSubset)\n\t\t\t{\n\t\t\t    // At this point I know this this Clause's\n\t\t\t    // literal/arity names are a subset of the\n\t\t\t    // other clauses literal/arity names\n\t\t\t    subsumes = checkSubsumes(othC, thisToTry, othCToTry);\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\n\t    return subsumes;\n\t}\n\n\t// Note: Applies binary resolution rule and factoring\n\t// Note: returns a set with an empty clause if both clauses\n\t// are empty, otherwise returns a set of binary resolvents.\n\tpublic List<Clause> binaryResolvents(Clause othC)\n\t{\n\t    List<Clause> resolvents = new List<Clause>();\n\t    // Resolving two empty clauses\n\t    // gives you an empty clause\n\t    if (isEmpty() && othC.isEmpty())\n\t    {\n\t\tresolvents.Add(new Clause());\n\t\treturn resolvents;\n\t    }\n\n\t    // Ensure Standardized Apart\n\t    // Before attempting binary resolution\n\t    othC = saIfRequired(othC);\n\n\t    List<Literal> allPosLits = new List<Literal>();\n\t    List<Literal> allNegLits = new List<Literal>();\n\t    allPosLits.AddRange(this.positiveLiterals);\n\t    allPosLits.AddRange(othC.positiveLiterals);\n\t    allNegLits.AddRange(this.negativeLiterals);\n\t    allNegLits.AddRange(othC.negativeLiterals);\n\n\t    List<Literal> trPosLits = new List<Literal>();\n\t    List<Literal> trNegLits = new List<Literal>();\n\t    List<Literal> copyRPosLits = new List<Literal>();\n\t    List<Literal> copyRNegLits = new List<Literal>();\n\n\t    for (int i = 0; i < 2; i++)\n\t    {\n\t\ttrPosLits.Clear();\n\t\ttrNegLits.Clear();\n\n\t\tif (i == 0)\n\t\t{\n\t\t    // See if this clauses positives\n\t\t    // unify with the other clauses\n\t\t    // negatives\n\t\t    trPosLits.AddRange(this.positiveLiterals);\n\t\t    trNegLits.AddRange(othC.negativeLiterals);\n\t\t}\n\t\telse\n\t\t{\n\t\t    // Try the other way round now\n\t\t    trPosLits.AddRange(othC.positiveLiterals);\n\t\t    trNegLits.AddRange(this.negativeLiterals);\n\t\t}\n\n\t\t// Now check to see if they resolve\n\t\tDictionary<Variable, Term> copyRBindings = new Dictionary<Variable, Term>();\n\t\tforeach (Literal pl in trPosLits)\n\t\t{\n\t\t    foreach (Literal nl in trNegLits)\n\t\t    {\n\t\t\tcopyRBindings.Clear();\n\t\t\tif (null != _unifier.unify(pl.getAtomicSentence(), nl\n\t\t\t\t.getAtomicSentence(), copyRBindings))\n\t\t\t{\n\t\t\t    copyRPosLits.Clear();\n\t\t\t    copyRNegLits.Clear();\n\t\t\t    bool found = false;\n\t\t\t    foreach (Literal l in allPosLits)\n\t\t\t    {\n\t\t\t\tif (!found && pl.Equals(l))\n\t\t\t\t{\n\t\t\t\t    found = true;\n\t\t\t\t    continue;\n\t\t\t\t}\n\t\t\t\tcopyRPosLits.Add(_substVisitor.subst(copyRBindings,\n\t\t\t\t\tl));\n\t\t\t    }\n\t\t\t    found = false;\n\t\t\t    foreach (Literal l in allNegLits)\n\t\t\t    {\n\t\t\t\tif (!found && nl.Equals(l))\n\t\t\t\t{\n\t\t\t\t    found = true;\n\t\t\t\t    continue;\n\t\t\t\t}\n\t\t\t\tcopyRNegLits.Add(_substVisitor.subst(copyRBindings,\n\t\t\t\t\tl));\n\t\t\t    }\n\t\t\t    // Ensure the resolvents are standardized apart\n\t\t\t    Dictionary<Variable, Term> renameSubstitituon = _standardizeApart\n\t\t\t\t    .standardizeApart(copyRPosLits, copyRNegLits,\n\t\t\t\t\t    _saIndexical);\n\t\t\t    Clause c = new Clause(copyRPosLits, copyRNegLits);\n\t\t\t    c.setProofStep(new ProofStepClauseBinaryResolvent(c,\n\t\t\t\t    this, othC, copyRBindings, renameSubstitituon));\n\t\t\t    if (isImmutable())\n\t\t\t    {\n\t\t\t\tc.setImmutable();\n\t\t\t    }\n\t\t\t    if (!isStandardizedApartCheckRequired())\n\t\t\t    {\n\t\t\t\tc.setStandardizedApartCheckNotRequired();\n\t\t\t    }\n\t\t\t    resolvents.Add(c);\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\t    return resolvents;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    if (null == stringRep)\n\t    {\n\t\tList<Literal> sortedLiterals = new List<Literal>(literals);\n\t\tsortedLiterals.Sort(_literalSorter);\n\n\t\tstringRep = sortedLiterals.ToString();\n\t    }\n\t    return stringRep;\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    return equalityIdentity.GetHashCode();\n\t}\n\n\tpublic override bool Equals(Object othObj)\n\t{\n\t    if (null == othObj)\n\t    {\n\t\treturn false;\n\t    }\n\t    if (this == othObj)\n\t    {\n\t\treturn true;\n\t    }\n\t    if (!(othObj is Clause))\n\t    {\n\t\treturn false;\n\t    }\n\t    Clause othClause = (Clause)othObj;\n\n\t    return equalityIdentity.Equals(othClause.equalityIdentity);\n\t}\n\n\tpublic String getEqualityIdentity()\n\t{\n\t    return equalityIdentity;\n\t}\n\n\t//\n\t// PRIVATE METHODS\n\t//\n\tprivate void recalculateIdentity()\n\t{\n\t    lock (equalityIdentity)\n\t    {\n\n\t\t// Sort the literals first based on negation, atomic sentence,\n\t\t// constant, function and variable.\n\t\tList<Literal> sortedLiterals = new List<Literal>(literals);\n\t\tsortedLiterals.Sort(_literalSorter);\n\n\t\t// All variables are considered the same as regards\n\t\t// sorting. Therefore, to determine if two clauses\n\t\t// are equivalent you need to determine\n\t\t// the # of unique variables they contain and\n\t\t// there positions across the clauses\n\t\tClauseEqualityIdentityConstructor ceic = new ClauseEqualityIdentityConstructor(\n\t\t\tsortedLiterals, _literalSorter);\n\n\t\tequalityIdentity = ceic.getIdentity();\n\n\t\t// Reset, these as will need to re-calcualte\n\t\t// if requested for again, best to only\n\t\t// access lazily.\n\t\tfactors = null;\n\t\tnonTrivialFactors = null;\n\t\t// Reset the objects string representation\n\t\t// until it is requested for.\n\t\tstringRep = null;\n\t    }\n\t}\n\n\tprivate void calculateFactors(List<Clause> parentFactors)\n\t{\n\t    nonTrivialFactors = new List<Clause>();\n\n\t    Dictionary<Variable, Term> theta = new Dictionary<Variable, Term>();\n\t    List<Literal> lits = new List<Literal>();\n\t    for (int i = 0; i < 2; i++)\n\t    {\n\t\tlits.Clear();\n\t\tif (i == 0)\n\t\t{\n\t\t    // Look at the positive literals\n\t\t    lits.AddRange(positiveLiterals);\n\t\t}\n\t\telse\n\t\t{\n\t\t    // Look at the negative literals\n\t\t    lits.AddRange(negativeLiterals);\n\t\t}\n\t\tfor (int x = 0; x < lits.Count; x++)\n\t\t{\n\t\t    for (int y = x + 1; y < lits.Count; y++)\n\t\t    {\n\t\t\tLiteral litX = lits[x];\n\t\t\tLiteral litY = lits[y];\n\n\t\t\ttheta.Clear();\n\t\t\tDictionary<Variable, Term> substitution = _unifier.unify(litX\n\t\t\t\t.getAtomicSentence(), litY.getAtomicSentence(),\n\t\t\t\ttheta);\n\t\t\tif (null != substitution)\n\t\t\t{\n\t\t\t    List<Literal> posLits = new List<Literal>();\n\t\t\t    List<Literal> negLits = new List<Literal>();\n\t\t\t    if (i == 0)\n\t\t\t    {\n\t\t\t\tposLits\n\t\t\t\t\t.Add(_substVisitor\n\t\t\t\t\t\t.subst(substitution, litX));\n\t\t\t    }\n\t\t\t    else\n\t\t\t    {\n\t\t\t\tnegLits\n\t\t\t\t\t.Add(_substVisitor\n\t\t\t\t\t\t.subst(substitution, litX));\n\t\t\t    }\n\t\t\t    foreach (Literal pl in positiveLiterals)\n\t\t\t    {\n\t\t\t\tif (pl == litX || pl == litY)\n\t\t\t\t{\n\t\t\t\t    continue;\n\t\t\t\t}\n\t\t\t\tposLits.Add(_substVisitor.subst(substitution, pl));\n\t\t\t    }\n\t\t\t    foreach (Literal nl in negativeLiterals)\n\t\t\t    {\n\t\t\t\tif (nl == litX || nl == litY)\n\t\t\t\t{\n\t\t\t\t    continue;\n\t\t\t\t}\n\t\t\t\tnegLits.Add(_substVisitor.subst(substitution, nl));\n\t\t\t    }\n\t\t\t    // Ensure the non trivial factor is standardized apart\n\t\t\t    _standardizeApart.standardizeApart(posLits, negLits,\n\t\t\t\t    _saIndexical);\n\t\t\t    Clause c = new Clause(posLits, negLits);\n\t\t\t    c.setProofStep(new ProofStepClauseFactor(c, this, null, null, null, null));\n\t\t\t    if (isImmutable())\n\t\t\t    {\n\t\t\t\tc.setImmutable();\n\t\t\t    }\n\t\t\t    if (!isStandardizedApartCheckRequired())\n\t\t\t    {\n\t\t\t\tc.setStandardizedApartCheckNotRequired();\n\t\t\t    }\n\t\t\t    if (null == parentFactors)\n\t\t\t    {\n\t\t\t\tc.calculateFactors(nonTrivialFactors);\n\t\t\t\tnonTrivialFactors.AddRange(c.getFactors());\n\t\t\t    }\n\t\t\t    else\n\t\t\t    {\n\t\t\t\tif (!parentFactors.Contains(c))\n\t\t\t\t{\n\t\t\t\t    c.calculateFactors(nonTrivialFactors);\n\t\t\t\t    nonTrivialFactors.AddRange(c.getFactors());\n\t\t\t\t}\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t    }\n\n\t    factors = new List<Clause>();\n\t    // Need to add self, even though a non-trivial\n\t    // factor. See: slide 30\n\t    // http://logic.stanford.edu/classes/cs157/2008/lectures/lecture10.pdf\n\t    // for example of incompleteness when\n\t    // trivial factor not included.\n\t    factors.Add(this);\n\t    factors.AddRange(nonTrivialFactors);\n\t}\n\n\tprivate Clause saIfRequired(Clause othClause)\n\t{\n\n\t    // If performing resolution with self\n\t    // then need to standardize apart in\n\t    // order to work correctly.\n\t    if (isStandardizedApartCheckRequired() || this == othClause)\n\t    {\n\t\tList<Variable> mVariables = _variableCollector\n\t\t\t.collectAllVariables(this);\n\t\tList<Variable> oVariables = _variableCollector\n\t\t\t.collectAllVariables(othClause);\n\n\t\tList<Variable> cVariables = new List<Variable>();\n\t\tcVariables.AddRange(mVariables);\n\t\tcVariables.AddRange(oVariables);\n\n\t\tif (cVariables.Count < (mVariables.Count + oVariables.Count))\n\t\t{\n\t\t    othClause = _standardizeApart.standardizeApart(othClause,\n\t\t\t    _saIndexical);\n\t\t}\n\t    }\n\n\t    return othClause;\n\t}\n\n\tprivate Dictionary<String, List<Literal>> collectLikeLiterals(List<Literal> literals)\n\t{\n\t    Dictionary<String, List<Literal>> likeLiterals = new Dictionary<String, List<Literal>>();\n\t    foreach (Literal l in literals)\n\t    {\n\t\t// Want to ensure P(a, b) is considered different than P(a, b, c)\n\t\t// i.e. consider an atom's arity P/#.\n\t\tString literalName = (l.isNegativeLiteral() ? \"~\" : \"\")\n\t\t\t+ l.getAtomicSentence().getSymbolicName() + \"/\"\n\t\t\t+ l.getAtomicSentence().getArgs().Count;\n\t\tList<Literal> like = null;\n\t\tif (likeLiterals.ContainsKey(literalName))\n\t\t{\n\t\t    like = likeLiterals[literalName];\n\t\t}\n\t\tif (null == like)\n\t\t{\n\t\t    like = new List<Literal>();\n\t\t    likeLiterals.Add(literalName, like);\n\t\t}\n\t\tlike.Add(l);\n\t    }\n\t    return likeLiterals;\n\t}\n\n\tprivate bool checkSubsumes(Clause othC,\n\t\tDictionary<String, List<Literal>> thisToTry,\n\t\tDictionary<String, List<Literal>> othCToTry)\n\t{\n\t    bool subsumes = false;\n\n\t    List<Term> thisTerms = new List<Term>();\n\t    List<Term> othCTerms = new List<Term>();\n\n\t    // Want to track possible number of permuations\n\t    List<int> radixs = new List<int>();\n\t    foreach (String literalName in thisToTry.Keys)\n\t    {\n\t\tint sizeT = thisToTry[literalName].Count;\n\t\tint sizeO = othCToTry[literalName].Count;\n\n\t\tif (sizeO > 1)\n\t\t{\n\t\t    // The following is being used to\n\t\t    // track the number of permutations\n\t\t    // that can be mapped from the\n\t\t    // other clauses like literals to this\n\t\t    // clauses like literals.\n\t\t    // i.e. n!/(n-r)!\n\t\t    // where n=sizeO and r =sizeT\n\t\t    for (int i = 0; i < sizeT; i++)\n\t\t    {\n\t\t\tint r = sizeO - i;\n\t\t\tif (r > 1)\n\t\t\t{\n\t\t\t    radixs.Add(r);\n\t\t\t}\n\t\t    }\n\t\t}\n\t\t// Track the terms for this clause\n\t\tforeach (Literal tl in thisToTry[literalName])\n\t\t{\n\t\t    List<Term> folNodes = tl.getAtomicSentence().getArgs();\n\t\t    foreach (FOLNode n in folNodes)\n\t\t    {\n\t\t\tthisTerms.Add((Term)n);\n\t\t    }\n\t\t}\n\t    }\n\n\t    MixedRadixNumber permutation = null;\n\t    long numPermutations = 1L;\n\t    if (radixs.Count > 0)\n\t    {\n\t\tpermutation = new MixedRadixNumber(0, radixs);\n\t\tnumPermutations = permutation.getMaxAllowedValue() + 1;\n\t    }\n\t    // Want to ensure none of the othCVariables are\n\t    // part of the key set of a unification as\n\t    // this indicates it is not a legal subsumption.\n\t    List<Variable> othCVariables = _variableCollector\n\t\t    .collectAllVariables(othC);\n\t    Dictionary<Variable, Term> theta = new Dictionary<Variable, Term>();\n\t    List<Literal> literalPermuations = new List<Literal>();\n\t    for (long l = 0L; l < numPermutations; l++)\n\t    {\n\t\t// Track the other clause's terms for this\n\t\t// permutation.\n\t\tothCTerms.Clear();\n\t\tint radixIdx = 0;\n\t\tforeach (String literalName in thisToTry.Keys)\n\t\t{\n\t\t    int sizeT = thisToTry[literalName].Count;\n\t\t    literalPermuations.Clear();\n\t\t    literalPermuations.AddRange(othCToTry[literalName]);\n\t\t    int sizeO = literalPermuations.Count;\n\n\t\t    if (sizeO > 1)\n\t\t    {\n\t\t\tfor (int i = 0; i < sizeT; i++)\n\t\t\t{\n\t\t\t    int r = sizeO - i;\n\t\t\t    if (r > 1)\n\t\t\t    {\n\t\t\t\t// If not a 1 to 1 mapping then you need\n\t\t\t\t// to use the correct permuation\n\t\t\t\tint numPos = permutation\n\t\t\t\t\t.getCurrentNumeralValue(radixIdx);\n\t\t\t\tLiteral lit = literalPermuations[numPos];\n\t\t\t\tliteralPermuations.Remove(lit);\n\t\t\t\tforeach (FOLNode arg in lit.getAtomicSentence().getArgs())\n\t\t\t\t{\n\t\t\t\t    othCTerms.Add((Term)arg);\n\t\t\t\t}\n\t\t\t\tradixIdx++;\n\t\t\t    }\n\t\t\t    else\n\t\t\t    {\n\t\t\t\t// is the last mapping, therefore\n\t\t\t\t// won't be on the radix\n\t\t\t\tforeach (FOLNode arg in literalPermuations[0].getAtomicSentence().getArgs())\n\t\t\t\t{\n\t\t\t\t    othCTerms.Add((Term)arg);\n\t\t\t\t}\n\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\t// a 1 to 1 mapping\n\t\t\tforeach (FOLNode arg in literalPermuations[0].getAtomicSentence().getArgs())\n\t\t\t{\n\t\t\t    othCTerms.Add((Term)arg);\n\t\t\t}\n\t\t    }\n\t\t}\n\n\t\t// Note: on unifier\n\t\t// unifier.unify(P(w, x), P(y, z)))={w=y, x=z}\n\t\t// unifier.unify(P(y, z), P(w, x)))={y=w, z=x}\n\t\t// Therefore want this clause to be the first\n\t\t// so can do the othCVariables check for an invalid\n\t\t// subsumes.\n\t\ttheta.Clear();\n\t\tList<FOLNode> termNodes = new List<FOLNode>();\n\t\tforeach (Term t in thisTerms)\n\t\t{\n\t\t    termNodes.Add((FOLNode)t);\n\t\t}\n\t\tList<FOLNode> othCNodes = new List<FOLNode>();\n\t\tforeach (Term t in othCTerms)\n\t\t{\n\t\t    othCNodes.Add((FOLNode)t);\n\t\t}\n\t\tif (null != _unifier.unify(termNodes, othCNodes, theta))\n\t\t{\n\t\t    bool containsAny = false;\n\t\t    foreach (Variable v in theta.Keys)\n\t\t    {\n\t\t\tif (othCVariables.Contains(v))\n\t\t\t{\n\t\t\t    containsAny = true;\n\t\t\t    break;\n\t\t\t}\n\t\t    }\n\t\t    if (!containsAny)\n\t\t    {\n\t\t\tsubsumes = true;\n\t\t\tbreak;\n\t\t    }\n\t\t}\n\n\t\t// If there is more than 1 mapping\n\t\t// keep track of where I am in the\n\t\t// possible number of mapping permutations.\n\t\tif (null != permutation)\n\t\t{\n\t\t    permutation.increment();\n\t\t}\n\t    }\n\n\t    return subsumes;\n\t}\n    }\n\n    class LiteralsSorter : IComparer<Literal>\n    {\n\tpublic int Compare(Literal o1, Literal o2)\n\t{\n\n\t    int rVal = 0;\n\t    // If literals are not negated the same\n\t    // then positive literals are considered\n\t    // (by convention here) to be of higher\n\t    // order than negative literals\n\t    if (o1.isPositiveLiteral() != o2.isPositiveLiteral())\n\t    {\n\t\tif (o1.isPositiveLiteral())\n\t\t{\n\t\t    return 1;\n\t\t}\n\t\treturn -1;\n\t    }\n\n\t    // Check their symbolic names for order first\n\t    rVal = o1.getAtomicSentence().getSymbolicName().CompareTo(\n\t\t    o2.getAtomicSentence().getSymbolicName());\n\n\t    // If have same symbolic names\n\t    // then need to compare individual arguments\n\t    // for order.\n\t    if (0 == rVal)\n\t    {\n\t\trVal = compareArgs(o1.getAtomicSentence().getArgs(), o2\n\t\t\t.getAtomicSentence().getArgs());\n\t    }\n\n\t    return rVal;\n\t}\n\n\tprivate int compareArgs(List<Term> args1, List<Term> args2)\n\t{\n\t    int rVal = 0;\n\n\t    // Compare argument sizes first\n\t    rVal = args1.Count - args2.Count;\n\n\t    if (0 == rVal && args1.Count > 0)\n\t    {\n\t\t// Move forward and compare the\n\t\t// first arguments\n\t\tTerm t1 = (Term)args1[0];\n\t\tTerm t2 = (Term)args2[0];\n\n\t\tif (t1.GetType().Equals(t2.GetType()))\n\t\t{\n\t\t    // Note: Variables are considered to have\n\t\t    // the same order\n\t\t    if (t1 is Constant)\n\t\t    {\n\t\t\trVal = t1.getSymbolicName().CompareTo(t2.getSymbolicName());\n\t\t    }\n\t\t    else if (t1 is Function)\n\t\t    {\n\t\t\trVal = t1.getSymbolicName().CompareTo(t2.getSymbolicName());\n\t\t\tif (0 == rVal)\n\t\t\t{\n\t\t\t    // Same function names, therefore\n\t\t\t    // compare the function arguments\n\t\t\t    rVal = compareArgs(t1.getArgs(), t2.getArgs());\n\t\t\t}\n\t\t    }\n\n\t\t    // If the first args are the same\n\t\t    // then compare the ordering of the\n\t\t    // remaining arguments\n\t\t    if (0 == rVal)\n\t\t    {\n\t\t\trVal = compareArgs(args1.Skip(1).ToList<Term>(), args2\n\t\t\t\t.Skip(1).ToList<Term>());\n\t\t    }\n\t\t}\n\t\telse\n\t\t{\n\t\t    // Order for different Terms is:\n\t\t    // Constant > Function > Variable\n\t\t    if (t1 is Constant)\n\t\t    {\n\t\t\trVal = 1;\n\t\t    }\n\t\t    else if (t2 is Constant)\n\t\t    {\n\t\t\trVal = -1;\n\t\t    }\n\t\t    else if (t1 is Function)\n\t\t    {\n\t\t\trVal = 1;\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\trVal = -1;\n\t\t    }\n\t\t}\n\t    }\n\n\t    return rVal;\n\t}\n\n\n    }\n\n    class ClauseEqualityIdentityConstructor : FOLVisitor\n    {\n\tprivate StringBuilder identity = new StringBuilder();\n\tprivate int noVarPositions = 0;\n\tprivate int[] clauseVarCounts = null;\n\tprivate int currentLiteral = 0;\n\tprivate Dictionary<String, List<int>> varPositions = new Dictionary<String, List<int>>();\n\n\tpublic ClauseEqualityIdentityConstructor(List<Literal> literals,\n\t\tLiteralsSorter sorter)\n\t{\n\n\t    clauseVarCounts = new int[literals.Count];\n\n\t    foreach (Literal l in literals)\n\t    {\n\t\tif (l.isNegativeLiteral())\n\t\t{\n\t\t    identity.Append(\"~\");\n\t\t}\n\t\tidentity.Append(l.getAtomicSentence().getSymbolicName());\n\t\tidentity.Append(\"(\");\n\t\tbool firstTerm = true;\n\t\tforeach (Term t in l.getAtomicSentence().getArgs())\n\t\t{\n\t\t    if (firstTerm)\n\t\t    {\n\t\t\tfirstTerm = false;\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\tidentity.Append(\",\");\n\t\t    }\n\t\t    t.accept(this, null);\n\t\t}\n\t\tidentity.Append(\")\");\n\t\tcurrentLiteral++;\n\t    }\n\n\t    int min, max;\n\t    min = max = 0;\n\t    for (int i = 0; i < literals.Count; i++)\n\t    {\n\t\tint incITo = i;\n\t\tint next = i + 1;\n\t\tmax += clauseVarCounts[i];\n\t\twhile (next < literals.Count)\n\t\t{\n\t\t    if (0 != sorter.Compare(literals[i], literals[next]))\n\t\t    {\n\t\t\tbreak;\n\t\t    }\n\t\t    max += clauseVarCounts[next];\n\t\t    incITo = next; // Need to skip to the end of the range\n\t\t    next++;\n\t\t}\n\t\t// This indicates two or more literals are identical\n\t\t// except for variable naming (note: identical\n\t\t// same name would be removed as are working\n\t\t// with sets so don't need to worry about this).\n\t\tif ((next - i) > 1)\n\t\t{\n\t\t    // Need to check each variable\n\t\t    // and if it has a position within the\n\t\t    // current min/max range then need\n\t\t    // to include its alternative\n\t\t    // sort order positions as well\n\t\t    foreach (String key in varPositions.Keys)\n\t\t    {\n\t\t\tList<int> positions = varPositions[key];\n\t\t\tList<int> additPositions = new List<int>();\n\t\t\t// Add then subtract for all possible\n\t\t\t// positions in range\n\t\t\tforeach (int pos in positions)\n\t\t\t{\n\t\t\t    if (pos >= min && pos < max)\n\t\t\t    {\n\t\t\t\tint pPos = pos;\n\t\t\t\tint nPos = pos;\n\t\t\t\tfor (int candSlot = i; candSlot < (next - 1); candSlot++)\n\t\t\t\t{\n\t\t\t\t    pPos += clauseVarCounts[i];\n\t\t\t\t    if (pPos >= min && pPos < max)\n\t\t\t\t    {\n\t\t\t\t\tif (!positions.Contains(pPos)\n\t\t\t\t\t\t&& !additPositions.Contains(pPos))\n\t\t\t\t\t{\n\t\t\t\t\t    additPositions.Add(pPos);\n\t\t\t\t\t}\n\t\t\t\t    }\n\t\t\t\t    nPos -= clauseVarCounts[i];\n\t\t\t\t    if (nPos >= min && nPos < max)\n\t\t\t\t    {\n\t\t\t\t\tif (!positions.Contains(nPos)\n\t\t\t\t\t\t&& !additPositions.Contains(nPos))\n\t\t\t\t\t{\n\t\t\t\t\t    additPositions.Add(nPos);\n\t\t\t\t\t}\n\t\t\t\t    }\n\t\t\t\t}\n\t\t\t    }\n\t\t\t}\n\t\t\tpositions.AddRange(additPositions);\n\t\t    }\n\t\t}\n\t\tmin = max;\n\t\ti = incITo;\n\t    }\n\n\t    // Determine the maxWidth\n\t    int maxWidth = 1;\n\t    while (noVarPositions >= 10)\n\t    {\n\t\tnoVarPositions = noVarPositions / 10;\n\t\tmaxWidth++;\n\t    }\n\t    String format = \"%0\" + maxWidth + \"d\";\n\n\t    // Sort the individual position lists\n\t    // And then add their string representations\n\t    // together\n\t    List<String> varOffsets = new List<String>();\n\t    foreach (String key in varPositions.Keys)\n\t    {\n\t\tList<int> positions = varPositions[key];\n\t\tpositions.Sort();\n\t\tStringBuilder sb = new StringBuilder();\n\t\tforeach (int pos in positions)\n\t\t{\n\t\t    sb.Append(String.Format(format, pos));\n\t\t}\n\t\tvarOffsets.Add(sb.ToString());\n\t    }\n\t    varOffsets.Sort();\n\t    for (int i = 0; i < varOffsets.Count; i++)\n\t    {\n\t\tidentity.Append(varOffsets[i]);\n\t\tif (i < (varOffsets.Count - 1))\n\t\t{\n\t\t    identity.Append(\",\");\n\t\t}\n\t    }\n\t}\n\n\tpublic String getIdentity()\n\t{\n\t    return identity.ToString();\n\t}\n\n\t// START-FOLVisitor\n\n\tpublic Object visitVariable(Variable var, Object arg)\n\t{\n\t    // All variables will be marked with an *\n\t    identity.Append(\"*\");\n\n\t    List<int> positions = null;\n\t    if (varPositions.ContainsKey(var.getValue()))\n\t    {\n\t\tpositions = varPositions[var.getValue()];\n\t    }\n\t    if (null == positions)\n\t    {\n\t\tpositions = new List<int>();\n\t\tvarPositions.Add(var.getValue(), positions);\n\t    }\n\t    positions.Add(noVarPositions);\n\n\t    noVarPositions++;\n\t    clauseVarCounts[currentLiteral]++;\n\t    return var;\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    identity.Append(constant.getValue());\n\t    return constant;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    bool firstTerm = true;\n\t    identity.Append(function.getFunctionName());\n\t    identity.Append(\"(\");\n\t    foreach (Term t in function.getTerms())\n\t    {\n\t\tif (firstTerm)\n\t\t{\n\t\t    firstTerm = false;\n\t\t}\n\t\telse\n\t\t{\n\t\t    identity.Append(\",\");\n\t\t}\n\t\tt.accept(this, arg);\n\t    }\n\t    identity.Append(\")\");\n\n\t    return function;\n\t}\n\n\tpublic Object visitPredicate(Predicate predicate, Object arg)\n\t{\n\t    throw new InvalidOperationException(\"Should not be called\");\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    throw new InvalidOperationException(\"Should not be called\");\n\t}\n\n\tpublic Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\tObject arg)\n\t{\n\t    throw new InvalidOperationException(\"Should not be called\");\n\t}\n\n\tpublic Object visitNotSentence(NotSentence sentence, Object arg)\n\t{\n\t    throw new InvalidOperationException(\"Should not be called\");\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    throw new InvalidOperationException(\"Should not be called\");\n\t}\n\n\t// END-FOLVisitor\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/kb/data/Literal.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Text;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.kb.data\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 244.<br>\n     * <br>\n     * A literal is either an atomic sentence (a positive literal) or a negated\n     * atomic sentence (a negative literal).\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class Literal\n    {\n\tprivate AtomicSentence atom = null;\n\tprivate bool negativeLiteral = false;\n\tprivate String strRep = null;\n\tprivate int hashCode = 0;\n\n\tpublic Literal(AtomicSentence atom)\n\t{\n\t    this.atom = atom;\n\t}\n\n\tpublic Literal(AtomicSentence atom, bool negated)\n\t{\n\t    this.atom = atom;\n\t    this.negativeLiteral = negated;\n\t}\n\n\tpublic virtual Literal newInstance(AtomicSentence atom)\n\t{\n\t    return new Literal(atom, negativeLiteral);\n\t}\n\n\tpublic bool isPositiveLiteral()\n\t{\n\t    return !negativeLiteral;\n\t}\n\n\tpublic bool isNegativeLiteral()\n\t{\n\t    return negativeLiteral;\n\t}\n\n\tpublic AtomicSentence getAtomicSentence()\n\t{\n\t    return atom;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    if (null == strRep)\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tif (isNegativeLiteral())\n\t\t{\n\t\t    sb.Append(\"~\");\n\t\t}\n\t\tsb.Append(getAtomicSentence().ToString());\n\t\tstrRep = sb.ToString();\n\t    }\n\n\t    return strRep;\n\t}\n\n\tpublic override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if (o.GetType() != this.GetType())\n\t    {\n\t\t// This prevents ReducedLiterals\n\t\t// being treated as equivalent to\n\t\t// normal Literals.\n\t\treturn false;\n\t    }\n\t    if (!(o is Literal))\n\t    {\n\t\treturn false;\n\t    }\n\t    Literal l = (Literal)o;\n\t    return l.isPositiveLiteral() == isPositiveLiteral()\n\t\t    && l.getAtomicSentence().getSymbolicName().Equals(\n\t\t\t    atom.getSymbolicName())\n\t\t    && l.getAtomicSentence().getArgs().Equals(atom.getArgs());\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    if (0 == hashCode)\n\t    {\n\t\thashCode = 17;\n\t\thashCode = 37 * hashCode + this.GetType().Name.GetHashCode()\n\t\t\t+ (isPositiveLiteral() ? \"+\".GetHashCode() : \"-\".GetHashCode())\n\t\t\t+ atom.getSymbolicName().GetHashCode();\n\t\tforeach (Term t in atom.getArgs())\n\t\t{\n\t\t    hashCode = 37 * hashCode + t.GetHashCode();\n\t\t}\n\t    }\n\t    return hashCode;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/kb/data/ReducedLiteral.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.kb.data\n{\n    /**\n     * @see <a\n     *      href=\"http://logic.stanford.edu/classes/cs157/2008/lectures/lecture13.pdf\"\n     *      >Reduced Literal</a>\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class ReducedLiteral : Literal\n    {\n\tprivate String strRep = null;\n\n\tpublic ReducedLiteral(AtomicSentence atom) : base(atom)\n\t{\n\n\t}\n\n\tpublic ReducedLiteral(AtomicSentence atom, bool negated) : base(atom, negated)\n\t{\n\n\t}\n\n\tpublic override Literal newInstance(AtomicSentence atom)\n\t{\n\t    return new ReducedLiteral(atom, isNegativeLiteral());\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    if (null == strRep)\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(\"[\");\n\t\tif (isNegativeLiteral())\n\t\t{\n\t\t    sb.Append(\"~\");\n\t\t}\n\t\tsb.Append(getAtomicSentence().ToString());\n\t\tsb.Append(\"]\");\n\t\tstrRep = sb.ToString();\n\t    }\n\n\t    return strRep;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/AbstractFOLVisitor.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.parsing\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public class AbstractFOLVisitor : FOLVisitor\n    {\n\tpublic AbstractFOLVisitor()\n\t{\n\t}\n\n\tprotected Sentence recreate(Object ast)\n\t{\n\t    return ((Sentence)ast).copySentence();\n\t}\n\n\tpublic virtual Object visitVariable(Variable variable, Object arg)\n\t{\n\t    return variable.copy();\n\t}\n\n\tpublic virtual Object visitQuantifiedSentence(QuantifiedSentence sentence,\n\t       Object arg)\n\t{\n\t    List<Variable> variables = new List<Variable>();\n\t    foreach (Variable var in sentence.getVariables())\n\t    {\n\t\tvariables.Add((Variable)var.accept(this, arg));\n\t    }\n\n\t    return new QuantifiedSentence(sentence.getQuantifier(), variables,\n\t\t    (Sentence)sentence.getQuantified().accept(this, arg));\n\t}\n\n\tpublic Object visitPredicate(Predicate predicate, Object arg)\n\t{\n\t    List<Term> terms = predicate.getTerms();\n\t    List<Term> newTerms = new List<Term>();\n\t    for (int i = 0; i < terms.Count; i++)\n\t    {\n\t\tTerm t = terms[i];\n\t\tTerm subsTerm = (Term)t.accept(this, arg);\n\t\tnewTerms.Add(subsTerm);\n\t    }\n\t    return new Predicate(predicate.getPredicateName(), newTerms);\n\t}\n\n\tpublic Object visitTermEquality(TermEquality equality, Object arg)\n\t{\n\t    Term newTerm1 = (Term)equality.getTerm1().accept(this, arg);\n\t    Term newTerm2 = (Term)equality.getTerm2().accept(this, arg);\n\t    return new TermEquality(newTerm1, newTerm2);\n\t}\n\n\tpublic Object visitConstant(Constant constant, Object arg)\n\t{\n\t    return constant;\n\t}\n\n\tpublic Object visitFunction(Function function, Object arg)\n\t{\n\t    List<Term> terms = function.getTerms();\n\t    List<Term> newTerms = new List<Term>();\n\t    for (int i = 0; i < terms.Count; i++)\n\t    {\n\t\tTerm t = terms[i];\n\t\tTerm subsTerm = (Term)t.accept(this, arg);\n\t\tnewTerms.Add(subsTerm);\n\t    }\n\t    return new Function(function.getFunctionName(), newTerms);\n\t}\n\n\tpublic Object visitNotSentence(NotSentence sentence, Object arg)\n\t{\n\t    return new NotSentence((Sentence)sentence.getNegated().accept(this,\n\t\t    arg));\n\t}\n\n\tpublic Object visitConnectedSentence(ConnectedSentence sentence, Object arg)\n\t{\n\t    Sentence substFirst = (Sentence)sentence.getFirst().accept(this, arg);\n\t    Sentence substSecond = (Sentence)sentence.getSecond()\n\t\t    .accept(this, arg);\n\t    return new ConnectedSentence(sentence.getConnector(), substFirst,\n\t\t    substSecond);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/FOLLexer.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing aima.core.logic.common;\nusing aima.core.logic.fol;\nusing aima.core.logic.fol.domain;\n\nnamespace aima.core.logic.fol.parsing\n{\n    /**\n     * @author Ciaran O'Reilly\n     * @author Ravi Mohan\n     * \n     */\n    public class FOLLexer : Lexer\n    {\n\tprivate FOLDomain domain;\n\tprivate HashSet<String> connectors, quantifiers;\n\n\tpublic FOLLexer(FOLDomain domain)\n\t{\n\t    this.domain = domain;\n\n\t    connectors = new HashSet<String>();\n\t    connectors.Add(Connectors.NOT);\n\t    connectors.Add(Connectors.AND);\n\t    connectors.Add(Connectors.OR);\n\t    connectors.Add(Connectors.IMPLIES);\n\t    connectors.Add(Connectors.BICOND);\n\n\t    quantifiers = new HashSet<String>();\n\t    quantifiers.Add(Quantifiers.FORALL);\n\t    quantifiers.Add(Quantifiers.EXISTS);\n\t}\n\n\tpublic FOLDomain getFOLDomain()\n\t{\n\t    return domain;\n\t}\n\n\tpublic override Token nextToken()\n\t{\n\t    int startPosition = getCurrentPositionInInput();\n\t    if (lookAhead(1) == '(')\n\t    {\n\t\tconsume();\n\t\treturn new Token((int)LogicTokenTypes.LPAREN, \"(\", startPosition);\n\n\t    }\n\t    else if (lookAhead(1) == ')')\n\t    {\n\t\tconsume();\n\t\treturn new Token((int)LogicTokenTypes.RPAREN, \")\", startPosition);\n\n\t    }\n\t    else if (lookAhead(1) == ',')\n\t    {\n\t\tconsume();\n\t\treturn new Token((int)LogicTokenTypes.COMMA, \",\", startPosition);\n\n\t    }\n\t    else if (identifierDetected())\n\t    {\n\t\t// System.Console.WriteLine(\"identifier detected\");\n\t\treturn identifier();\n\t    }\n\t    else if (char.IsWhiteSpace(lookAhead(1)))\n\t    {\n\t\tconsume();\n\t\treturn nextToken();\n\t    }\n\t    else if (lookAhead(1) == 65535)\n\t    {\n\t\treturn new Token((int)LogicTokenTypes.EOI, \"EOI\", startPosition);\n\t    }\n\t    else\n\t    {\n\t\tthrow new LexerException(\"Lexing error on character \" + lookAhead(1) + \" at position \" + getCurrentPositionInInput(), getCurrentPositionInInput());\n\t    }\n\t}\n\n\tprivate bool isCSharpIdentifierStart(char c)\n\t{\n\t    return char.IsLetter(c) || c == '_' || c == '$' || char.IsNumber(c);\n\t}\n\n\tprivate Token identifier()\n\t{\n\t    int startPosition = getCurrentPositionInInput();\n\t    StringBuilder sbuf = new StringBuilder();\n\t    while ((isCSharpIdentifierStart(lookAhead(1)))\n\t\t    || partOfConnector())\n\t    {\n\t\tsbuf.Append(lookAhead(1));\n\t\tconsume();\n\t    }\n\t    String readString = sbuf.ToString();\n\t    // System.Console.WriteLine(readString);\n\t    if (connectors.Contains(readString))\n\t    {\n\t\treturn new Token((int)LogicTokenTypes.CONNECTOR, readString, startPosition);\n\t    }\n\t    else if (quantifiers.Contains(readString))\n\t    {\n\t\treturn new Token((int)LogicTokenTypes.QUANTIFIER, readString, startPosition);\n\t    }\n\t    else if (domain.getPredicates().Contains(readString))\n\t    {\n\t\treturn new Token((int)LogicTokenTypes.PREDICATE, readString, startPosition);\n\t    }\n\t    else if (domain.getFunctions().Contains(readString))\n\t    {\n\t\treturn new Token((int)LogicTokenTypes.FUNCTION, readString, startPosition);\n\t    }\n\t    else if (domain.getConstants().Contains(readString))\n\t    {\n\t\treturn new Token((int)LogicTokenTypes.CONSTANT, readString, startPosition);\n\t    }\n\t    else if (isVariable(readString))\n\t    {\n\t\treturn new Token((int)LogicTokenTypes.VARIABLE, readString, startPosition);\n\t    }\n\t    else if (readString.Equals(\"=\"))\n\t    {\n\t\treturn new Token((int)LogicTokenTypes.EQUALS, readString, startPosition);\n\t    }\n\t    else\n\t    {\n\t\tthrow new LexerException(\"Lexing error on character \" + lookAhead(1) + \" at position \" + getCurrentPositionInInput(), getCurrentPositionInInput());\n\t    }\n\t}\n\n\tprivate bool isVariable(String s)\n\t{\n\t    return (char.IsLower(s[0]));\n\t}\n\n\tprivate bool identifierDetected()\n\t{\n\t    return (isCSharpIdentifierStart(((char)lookAheadBuffer[0]))\n\t\t    || partOfConnector());\n\t}\n\n\tprivate bool partOfConnector()\n\t{\n\t    return (lookAhead(1) == '=') || (lookAhead(1) == '<')\n\t\t\t    || (lookAhead(1) == '>');\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/FOLParser.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.common;\nusing aima.core.logic.fol.domain;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.parsing\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public class FOLParser\n    {\n\tprivate FOLLexer lexer;\n\n\tprotected Token[] lookAheadBuffer;\n\n\tprotected int LookAhead = 1;\n\n\tpublic FOLParser(FOLLexer lexer)\n\t{\n\t    this.lexer = lexer;\n\t    lookAheadBuffer = new Token[LookAhead];\n\t}\n\n\tpublic FOLParser(FOLDomain domain): this(new FOLLexer(domain))\n\t{\n\t    \n\t}\n\n\tpublic FOLDomain getFOLDomain()\n\t{\n\t    return lexer.getFOLDomain();\n\t}\n\n\tpublic Sentence parse(String s)\n\t{\n\t    setUpToParse(s);\n\t    return parseSentence();\n\t}\n\n\tpublic void setUpToParse(String s)\n\t{\n\t    lookAheadBuffer = new Token[1];\n\t    lexer.setInput(s);\n\t    fillLookAheadBuffer();\n\t}\n\n\tprivate Term parseTerm()\n\t{\n\t    Token t = lookAhead(1);\n\t    int tokenType = t.getType();\n\t    if (tokenType == (int)LogicTokenTypes.CONSTANT)\n\t    {\n\t\treturn parseConstant();\n\t    }\n\t    else if (tokenType == (int)LogicTokenTypes.VARIABLE)\n\t    {\n\t\treturn parseVariable();\n\t    }\n\t    else if (tokenType == (int)LogicTokenTypes.FUNCTION)\n\t    {\n\t\treturn parseFunction();\n\t    }\n\t    else\n\t    {\n\t\treturn null;\n\t    }\n\t}\n\n\tpublic Term parseVariable()\n\t{\n\t    Token t = lookAhead(1);\n\t    String value = t.getText();\n\t    consume();\n\t    return new Variable(value);\n\t}\n\n\tpublic Term parseConstant()\n\t{\n\t    Token t = lookAhead(1);\n\t    String value = t.getText();\n\t    consume();\n\t    return new Constant(value);\n\t}\n\n\tpublic Term parseFunction()\n\t{\n\t    Token t = lookAhead(1);\n\t    String functionName = t.getText();\n\t    List<Term> terms = processTerms();\n\t    return new Function(functionName, terms);\n\t}\n\n\tpublic Sentence parsePredicate()\n\t{\n\t    Token t = lookAhead(1);\n\t    String predicateName = t.getText();\n\t    List<Term> terms = processTerms();\n\t    return new Predicate(predicateName, terms);\n\t}\n\n\tprivate List<Term> processTerms()\n\t{\n\t    consume();\n\t    List<Term> terms = new List<Term>();\n\t    match(\"(\");\n\t    Term term = parseTerm();\n\t    terms.Add(term);\n\n\t    while (lookAhead(1).getType() == (int)LogicTokenTypes.COMMA)\n\t    {\n\t\tmatch(\",\");\n\t\tterm = parseTerm();\n\t\tterms.Add(term);\n\t    }\n\t    match(\")\");\n\t    return terms;\n\t}\n\n\tpublic Sentence parseTermEquality()\n\t{\n\t    Term term1 = parseTerm();\n\t    match(\"=\");\n\t    // System.Console.WriteLine(\"=\");\n\t    Term term2 = parseTerm();\n\t    return new TermEquality(term1, term2);\n\t}\n\n\tpublic Sentence parseNotSentence()\n\t{\n\t    match(\"NOT\");\n\t    return new NotSentence(parseSentence());\n\t}\n\n\t// PROTECTED METHODS\n\t\n\tprotected Token lookAhead(int i)\n\t{\n\t    return lookAheadBuffer[i - 1];\n\t}\n\n\tprotected void consume()\n\t{\n\t    // System.Console.WriteLine(\"consuming\" +lookAheadBuffer[0].getText());\n\t    loadNextTokenFromInput();\n\t    // System.Console.WriteLine(\"next token \" +lookAheadBuffer[0].getText());\n\t}\n\n\tprotected void loadNextTokenFromInput()\n\t{\n\n\t    bool eoiEncountered = false;\n\t    for (int i = 0; i < LookAhead - 1; i++)\n\t    {\n\n\t\tlookAheadBuffer[i] = lookAheadBuffer[i + 1];\n\t\tif (isEndOfInput(lookAheadBuffer[i]))\n\t\t{\n\t\t    eoiEncountered = true;\n\t\t    break;\n\t\t}\n\t    }\n\t    if (!eoiEncountered)\n\t    {\n\t\ttry\n\t\t{\n\t\t    lookAheadBuffer[LookAhead - 1] = lexer.nextToken();\n\t\t}\n\t\tcatch (Exception e)\n\t\t{\n\t\t    Console.WriteLine(e);\n\t\t}\n\t    }\n\t}\n\n\tprotected bool isEndOfInput(Token t)\n\t{\n\t    return (t.getType() == (int)LogicTokenTypes.EOI);\n\t}\n\n\tprotected void fillLookAheadBuffer()\n\t{\n\t    for (int i = 0; i < LookAhead; i++)\n\t    {\n\t\tlookAheadBuffer[i] = lexer.nextToken();\n\t    }\n\t}\n\n\tprotected void match(String terminalSymbol)\n\t{\n\t    if (lookAhead(1).getText().Equals(terminalSymbol))\n\t    {\n\t\tconsume();\n\t    }\n\t    else\n\t    {\n\t\tthrow new ApplicationException(\n\t\t\t\"Syntax error detected at match. Expected \"\n\t\t\t\t+ terminalSymbol + \" but got \"\n\t\t\t\t+ lookAhead(1).getText());\n\t    }\n\t}\n\n\t// PRIVATE METHODS\n\t\n\tprivate Sentence parseSentence()\n\t{\n\t    Token t = lookAhead(1);\n\t    if (lParen(t))\n\t    {\n\t\treturn parseParanthizedSentence();\n\t    }\n\t    else if ((lookAhead(1).getType() == (int)LogicTokenTypes.QUANTIFIER))\n\t    {\n\n\t\treturn parseQuantifiedSentence();\n\t    }\n\t    else if (notToken(t))\n\t    {\n\t\treturn parseNotSentence();\n\t    }\n\t    else if (predicate(t))\n\t    {\n\t\treturn parsePredicate();\n\t    }\n\t    else if (term(t))\n\t    {\n\t\treturn parseTermEquality();\n\t    }\n\n\t    throw new ApplicationException(\"parse failed with Token \" + t.getText());\n\t}\n\n\tprivate Sentence parseQuantifiedSentence()\n\t{\n\t    String quantifier = lookAhead(1).getText();\n\t    consume();\n\t    List<Variable> variables = new List<Variable>();\n\t    Variable var = (Variable)parseVariable();\n\t    variables.Add(var);\n\t    while (lookAhead(1).getType() == (int)LogicTokenTypes.COMMA)\n\t    {\n\t\tconsume();\n\t\tvar = (Variable)parseVariable();\n\t\tvariables.Add(var);\n\t    }\n\t    Sentence sentence = parseSentence();\n\t    return new QuantifiedSentence(quantifier, variables, sentence);\n\t}\n\n\tprivate Sentence parseParanthizedSentence()\n\t{\n\t    match(\"(\");\n\t    Sentence sen = parseSentence();\n\t    while (binaryConnector(lookAhead(1)))\n\t    {\n\t\tString connector = lookAhead(1).getText();\n\t\tconsume();\n\t\tSentence other = parseSentence();\n\t\tsen = new ConnectedSentence(connector, sen, other);\n\t    }\n\t    match(\")\");\n\t    return sen; /* new ParanthizedSentence */\n\n\t}\n\n\tprivate bool binaryConnector(Token t)\n\t{\n\t    if ((t.getType() == (int)LogicTokenTypes.CONNECTOR)\n\t\t\t    && (!(t.getText().Equals(\"NOT\"))))\n\t    {\n\t\treturn true;\n\t    }\n\t    else\n\t    {\n\t\treturn false;\n\t    }\n\t}\n\n\tprivate bool lParen(Token t)\n\t{\n\t    if (t.getType() == (int)LogicTokenTypes.LPAREN)\n\t    {\n\t\treturn true;\n\t    }\n\t    else\n\t    {\n\t\treturn false;\n\t    }\n\t}\n\n\tprivate bool term(Token t)\n\t{\n\t    if ((t.getType() == (int)LogicTokenTypes.FUNCTION)\n\t\t\t    || (t.getType() == (int)LogicTokenTypes.CONSTANT)\n\t\t\t    || (t.getType() == (int)LogicTokenTypes.VARIABLE))\n\t    {\n\t\treturn true;\n\t    }\n\t    else\n\t    {\n\t\treturn false;\n\t    }\n\n\t}\n\n\tprivate bool predicate(Token t)\n\t{\n\t    if ((t.getType() == (int)LogicTokenTypes.PREDICATE))\n\t    {\n\t\treturn true;\n\t    }\n\t    else\n\t    {\n\t\treturn false;\n\t    }\n\t}\n\n\tprivate bool notToken(Token t)\n\t{\n\t    if ((t.getType() == (int)LogicTokenTypes.CONNECTOR)\n\t\t\t    && (t.getText().Equals(\"NOT\")))\n\t    {\n\t\treturn true;\n\t    }\n\t    else\n\t    {\n\t\treturn false;\n\t    }\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/FOLVisitor.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.parsing.ast;\n\nnamespace aima.core.logic.fol.parsing\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public interface FOLVisitor\n    {\n\tObject visitPredicate(Predicate p, Object arg);\n\n\tObject visitTermEquality(TermEquality equality, Object arg);\n\n\tObject visitVariable(Variable variable, Object arg);\n\n\tObject visitConstant(Constant constant, Object arg);\n\n\tObject visitFunction(Function function, Object arg);\n\n\tObject visitNotSentence(NotSentence sentence, Object arg);\n\n\tObject visitConnectedSentence(ConnectedSentence sentence, Object arg);\n\n\tObject visitQuantifiedSentence(QuantifiedSentence sentence,\n\t\t\tObject arg);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/AtomicSentence.cs",
    "content": "using System.Collections.Generic;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface AtomicSentence : Sentence\n    {\n\tList<Term> getArgs();\n\n\tAtomicSentence copy();\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/ConnectedSentence.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing aima.core.logic.fol.parsing;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class ConnectedSentence : Sentence\n    {\n\tprivate String connector;\n\tprivate Sentence first, second;\n\tprivate List<Sentence> args = new List<Sentence>();\n\tprivate String stringRep = null;\n\tprivate int hashCode = 0;\n\n\tpublic ConnectedSentence(String connector, Sentence first, Sentence second)\n\t{\n\t    this.connector = connector;\n\t    this.first = first;\n\t    this.second = second;\n\t    args.Add(first);\n\t    args.Add(second);\n\t}\n\n\tpublic String getConnector()\n\t{\n\t    return connector;\n\t}\n\n\tpublic Sentence getFirst()\n\t{\n\t    return first;\n\t}\n\n\tpublic Sentence getSecond()\n\t{\n\t    return second;\n\t}\n\n\t// START-Sentence\n\n\tpublic String getSymbolicName()\n\t{\n\t    return getConnector();\n\t}\n\n\tpublic bool isCompound()\n\t{\n\t    return true;\n\t}\n\n\tpublic List<FOLNode> getArgs()\n\t{\n\t    Sentence[] copy = new Sentence[args.Count];\n\t    args.CopyTo(copy);\n\t    return new List<FOLNode>(copy);\n\t}\n\n\tpublic Object accept(FOLVisitor v, Object arg)\n\t{\n\t    return v.visitConnectedSentence(this, arg);\n\t}\n\n        public FOLNode copy()\n        {\n            return null;\n        }\n\n        public Sentence copySentence()\n\t{\n\t    return new ConnectedSentence(connector, first.copySentence(), second.copySentence());\n\t}\n\n\t// END-Sentence\n\n\tpublic override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if ((o == null) || !(o is ConnectedSentence))\n\t    {\n\t\treturn false;\n\t    }\n\t    ConnectedSentence cs = (ConnectedSentence)o;\n\t    return cs.getConnector().Equals(getConnector())\n\t\t    && cs.getFirst().Equals(getFirst())\n\t\t    && cs.getSecond().Equals(getSecond());\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    if (0 == hashCode)\n\t    {\n\t\thashCode = 17;\n\t\thashCode = 37 * hashCode + getConnector().GetHashCode();\n\t\thashCode = 37 * hashCode + getFirst().GetHashCode();\n\t\thashCode = 37 * hashCode + getSecond().GetHashCode();\n\t    }\n\t    return hashCode;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    if (null == stringRep)\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(\"(\");\n\t\tsb.Append(first.ToString());\n\t\tsb.Append(\" \");\n\t\tsb.Append(connector);\n\t\tsb.Append(\" \");\n\t\tsb.Append(second.ToString());\n\t\tsb.Append(\")\");\n\t\tstringRep = sb.ToString();\n\t    }\n\t    return stringRep;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/Constant.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.parsing;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class Constant : Term\n    {\n\tprivate String value;\n\tprivate int hashCode = 0;\n\n\tpublic Constant(String s)\n\t{\n\t    value = s;\n\t}\n\n\tpublic String getValue()\n\t{\n\t    return value;\n\t}\n\n\t// START-Term\n\n\tpublic String getSymbolicName()\n\t{\n\t    return getValue();\n\t}\n\n\tpublic bool isCompound()\n\t{\n\t    return false;\n\t}\n\n        List<FOLNode> FOLNode.getArgs()\n        {\n            return null;\n        }\n\n        public List<Term> getArgs()\n\t{\n\t    // Is not Compound, therefore should\n\t    // return null for its arguments\n\t    return null;\n\t}\n\n\tpublic Object accept(FOLVisitor v, Object arg)\n\t{\n\t    return v.visitConstant(this, arg);\n\t}\n\n        FOLNode FOLNode.copy()\n        {\n            return copy();\n        }\n\n        public Term copy()\n\t{\n\t    return new Constant(value);\n\t}\n\n\t// END-Term\n\n\tpublic override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if (!(o is Constant))\n\t    {\n\t\treturn false;\n\t    }\n\t    Constant c = (Constant)o;\n\t    return c.getValue().Equals(getValue());\n\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    if (0 == hashCode)\n\t    {\n\t\thashCode = 17;\n\t\thashCode = 37 * hashCode + value.GetHashCode();\n\t    }\n\t    return hashCode;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    return value;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/FOLNode.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.common;\nusing aima.core.logic.fol.parsing;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public interface FOLNode : ParseTreeNode\n    {\n\tString getSymbolicName();\n\n\tbool isCompound();\n\n\tList<FOLNode> getArgs();\n\n\tObject accept(FOLVisitor v, Object arg);\n\n\tFOLNode copy();\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/Function.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing aima.core.logic.fol.parsing;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class Function : Term\n    {\n\tprivate String functionName;\n\tprivate List<Term> terms = new List<Term>();\n\tprivate String stringRep = null;\n\tprivate int hashCode = 0;\n\n\tpublic Function(String functionName, List<Term> terms)\n\t{\n\t    this.functionName = functionName;\n\t    this.terms.AddRange(terms);\n\t}\n\n\tpublic String getFunctionName()\n\t{\n\t    return functionName;\n\t}\n\n\tpublic List<Term> getTerms()\n\t{\n\t    Term[] copy = new Term[terms.Count];\n\t    terms.CopyTo(copy);\n\t    return new List<Term>(copy);\n\t}\n\n\t// START-Term\n\n\tpublic String getSymbolicName()\n\t{\n\t    return getFunctionName();\n\t}\n\n\tpublic bool isCompound()\n\t{\n\t    return true;\n\t}\n\n        List<FOLNode> FOLNode.getArgs()\n        {\n            return null;\n        }\n\n        public List<Term> getArgs()\n\t{\n\t    return getTerms();\n\t}\n\n\tpublic Object accept(FOLVisitor v, Object arg)\n\t{\n\t    return v.visitFunction(this, arg);\n\t}\n\n        FOLNode FOLNode.copy()\n        {\n            return copy();\n        }\n\n        public Term copy()\n\t{\n\t    List<Term> copyTerms = new List<Term>();\n\t    foreach (Term t in terms)\n\t    {\n\t\tcopyTerms.Add(t.copy());\n\t    }\n\t    return new Function(functionName, copyTerms);\n\t}\n\n\t// END-Term\n\n\tpublic override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if (!(o is Function))\n\t    {\n\t\treturn false;\n\t    }\n\n\t    Function f = (Function)o;\n\n\t    return f.getFunctionName().Equals(getFunctionName())\n\t\t    && f.getTerms().Equals(getTerms());\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    if (0 == hashCode)\n\t    {\n\t\thashCode = 17;\n\t\thashCode = 37 * hashCode + functionName.GetHashCode();\n\t\tforeach (Term t in terms)\n\t\t{\n\t\t    hashCode = 37 * hashCode + t.GetHashCode();\n\t\t}\n\t    }\n\t    return hashCode;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    if (null == stringRep)\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(functionName);\n\t\tsb.Append(\"(\");\n\n\t\tbool first = true;\n\t\tforeach (Term t in terms)\n\t\t{\n\t\t    if (first)\n\t\t    {\n\t\t\tfirst = false;\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\tsb.Append(\",\");\n\t\t    }\n\t\t    sb.Append(t.ToString());\n\t\t}\n\n\t\tsb.Append(\")\");\n\n\t\tstringRep = sb.ToString();\n\t    }\n\t    return stringRep;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/NotSentence.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Linq;\nusing aima.core.logic.fol;\nusing aima.core.logic.fol.parsing;\nusing aima.core.logic.fol.inference.proof;\nusing System.Collections.ObjectModel;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class NotSentence : Sentence\n    {\n\tprivate Sentence negated;\n\tprivate List<Sentence> args = new List<Sentence>();\n\tprivate String stringRep = null;\n\tprivate int hashCode = 0;\n\n\tpublic NotSentence(Sentence negated)\n\t{\n\t    this.negated = negated;\n\t    args.Add(negated);\n\t}\n\n\tpublic Sentence getNegated()\n\t{\n\t    return negated;\n\t}\n\n\t// START-Sentence\n\n\tpublic String getSymbolicName()\n\t{\n\t    return Connectors.NOT;\n\t}\n\n\tpublic bool isCompound()\n\t{\n\t    return true;\n\t}\n\n\tpublic List<FOLNode> getArgs()\n\t{\n\t    return new ReadOnlyCollection<Sentence>(args).ToList<FOLNode>();\n\t}\n\n\tpublic Object accept(FOLVisitor v, Object arg)\n\t{\n\t    return v.visitNotSentence(this, arg);\n\t}\n\n\tpublic FOLNode copy()\n\t{\n\t    return new NotSentence((Sentence)negated.copy());\n\t}\n\n        public Sentence copySentence()\n        {\n            return null;\n        }\n\n        // END-Sentence\n\n\tpublic override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if ((o == null) || !(o is NotSentence))\n\t    {\n\t\treturn false;\n\t    }\n\t    NotSentence ns = (NotSentence)o;\n\t    return (ns.negated.Equals(negated));\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    if (0 == hashCode)\n\t    {\n\t\thashCode = 17;\n\t\thashCode = 37 * hashCode + negated.GetHashCode();\n\t    }\n\t    return hashCode;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    if (null == stringRep)\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(\"NOT(\");\n\t\tsb.Append(negated.ToString());\n\t\tsb.Append(\")\");\n\t\tstringRep = sb.ToString();\n\t    }\n\t    return stringRep;\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/Predicate.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Linq;\nusing aima.core.logic.fol.parsing;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class Predicate : AtomicSentence\n    {\n\tprivate String predicateName;\n\tprivate List<Term> terms = new List<Term>();\n\tprivate String stringRep = null;\n\tprivate int hashCode = 0;\n\n\tpublic Predicate(String predicateName, List<Term> terms)\n\t{\n\t    this.predicateName = predicateName;\n\t    this.terms.AddRange(terms);\n\t}\n\n\tpublic String getPredicateName()\n\t{\n\t    return predicateName;\n\t}\n\n\tpublic List<Term> getTerms()\n\t{\n\t    return terms.AsReadOnly().ToList<Term>();\n\t}\n\n\t// START-AtomicSentence\n\n\tpublic String getSymbolicName()\n\t{\n\t    return getPredicateName();\n\t}\n\n\tpublic bool isCompound()\n\t{\n\t    return true;\n\t}\n\n        List<FOLNode> FOLNode.getArgs()\n        {\n            return null;\n        }\n\n        AtomicSentence AtomicSentence.copy()\n        {\n            return null;\n        }\n\n        public List<Term> getArgs()\n\t{\n\t    return getTerms();\n\t}\n\n\tpublic Object accept(FOLVisitor v, Object arg)\n\t{\n\t    return v.visitPredicate(this, arg);\n\t}\n\n\tpublic FOLNode copy()\n\t{\n\t    List<Term> copyTerms = new List<Term>();\n\t    foreach (Term t in terms)\n\t    {\n\t\tcopyTerms.Add(t.copy());\n\t    }\n\t    return new Predicate(predicateName, copyTerms);\n\t}\n\n        public Sentence copySentence()\n        {\n            return null;\n        }\n\n        // END-AtomicSentence\n\n\tpublic override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if (!(o is Predicate))\n\t    {\n\t\treturn false;\n\t    }\n\t    Predicate p = (Predicate)o;\n\t    return p.getPredicateName().Equals(getPredicateName())\n\t\t    && p.getTerms().Equals(getTerms());\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    if (0 == hashCode)\n\t    {\n\t\thashCode = 17;\n\t\thashCode = 37 * hashCode + predicateName.GetHashCode();\n\t\tforeach (Term t in terms)\n\t\t{\n\t\t    hashCode = 37 * hashCode + t.GetHashCode();\n\t\t}\n\t    }\n\t    return hashCode;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    if (null == stringRep)\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(predicateName);\n\t\tsb.Append(\"(\");\n\n\t\tbool first = true;\n\t\tforeach (Term t in terms)\n\t\t{\n\t\t    if (first)\n\t\t    {\n\t\t\tfirst = false;\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\tsb.Append(\",\");\n\t\t    }\n\t\t    sb.Append(t.ToString());\n\t\t}\n\n\t\tsb.Append(\")\");\n\t\tstringRep = sb.ToString();\n\t    }\n\t    return stringRep;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/QuantifiedSentence.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.parsing;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class QuantifiedSentence : Sentence\n    {\n\tprivate String quantifier;\n\tprivate List<Variable> variables = new List<Variable>();\n\tprivate Sentence quantified;\n\tprivate List<FOLNode> args = new List<FOLNode>();\n\tprivate String stringRep = null;\n\tprivate int hashCode = 0;\n\n\tpublic QuantifiedSentence(String quantifier, List<Variable> variables,\n\t       Sentence quantified)\n\t{\n\t    this.quantifier = quantifier;\n\t    this.variables.AddRange(variables);\n\t    this.quantified = quantified;\n\t    this.args.AddRange(variables);\n\t    this.args.Add(quantified);\n\t}\n\n\tpublic String getQuantifier()\n\t{\n\t    return quantifier;\n\t}\n\n\tpublic List<Variable> getVariables()\n\t{\n\t    return new ReadOnlyCollection<Variable>(variables).ToList<Variable>();\n\t}\n\n\tpublic Sentence getQuantified()\n\t{\n\t    return quantified;\n\t}\n\n\t// START-Sentence\n\n\tpublic String getSymbolicName()\n\t{\n\t    return getQuantifier();\n\t}\n\n\tpublic bool isCompound()\n\t{\n\t    return true;\n\t}\n\n\tpublic List<FOLNode> getArgs()\n\t{\n\t    return new ReadOnlyCollection<FOLNode>(args).ToList<FOLNode>();\n\t}\n\n\tpublic Object accept(FOLVisitor v, Object arg)\n\t{\n\t    return v.visitQuantifiedSentence(this, arg);\n\t}\n\n\tpublic FOLNode copy()\n\t{\n\t    List<Variable> copyVars = new List<Variable>();\n\t    foreach (Variable v in variables)\n\t    {\n\t\tcopyVars.Add((Variable)v.copy());\n\t    }\n\t    return new QuantifiedSentence(quantifier, copyVars, quantified.copySentence());\n\t}\n\n        public Sentence copySentence()\n        {\n            return null;\n        }\n\n        // END-Sentence\n\n\tpublic override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if ((o == null) || !(o is QuantifiedSentence))\n\t    {\n\t\treturn false;\n\t    }\n\t    QuantifiedSentence cs = (QuantifiedSentence)o;\n\t    return cs.quantifier.Equals(quantifier)\n\t\t\t    && cs.variables.Equals(variables)\n\t\t\t    && cs.quantified.Equals(quantified);\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    if (0 == hashCode)\n\t    {\n\t\thashCode = 17;\n\t\thashCode = 37 * hashCode + quantifier.GetHashCode();\n\t\tforeach (Variable v in variables)\n\t\t{\n\t\t    hashCode = 37 * hashCode + v.GetHashCode();\n\t\t}\n\t\thashCode = hashCode * 37 + quantified.GetHashCode();\n\t    }\n\t    return hashCode;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    if (null == stringRep)\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(quantifier);\n\t\tsb.Append(\" \");\n\t\tforeach (Variable v in variables)\n\t\t{\n\t\t    sb.Append(v.ToString());\n\t\t    sb.Append(\" \");\n\t\t}\n\t\tsb.Append(quantified.ToString());\n\t\tstringRep = sb.ToString();\n\t    }\n\t    return stringRep;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/Sentence.cs",
    "content": "using System.Collections.Generic;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public interface Sentence : FOLNode\n    {\n\tSentence copySentence();\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/Term.cs",
    "content": "using System.Collections.Generic;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public interface Term : FOLNode\n    {\n\tList<Term> getArgs();\n\n\tTerm copy();\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/TermEquality.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Linq;\nusing System.Collections.ObjectModel;\nusing aima.core.logic.fol.parsing;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class TermEquality : AtomicSentence\n    {\n\tprivate Term term1, term2;\n\tprivate List<Term> terms = new List<Term>();\n\tprivate String stringRep = null;\n\tprivate int hashCode = 0;\n\n\tpublic static String getEqualitySynbol()\n\t{\n\t    return \"=\";\n\t}\n\n\tpublic TermEquality(Term term1, Term term2)\n\t{\n\t    this.term1 = term1;\n\t    this.term2 = term2;\n\t    terms.Add(term1);\n\t    terms.Add(term2);\n\t}\n\n\tpublic Term getTerm1()\n\t{\n\t    return term1;\n\t}\n\n\tpublic Term getTerm2()\n\t{\n\t    return term2;\n\t}\n\t\t\n\t// START-AtomicSentence\n\n\tpublic String getSymbolicName()\n\t{\n\t    return getEqualitySynbol();\n\t}\n\n\tpublic bool isCompound()\n\t{\n\t    return true;\n\t}\n\n        List<Term> AtomicSentence.getArgs()\n        {\n            return null;\n        }\n\n        AtomicSentence AtomicSentence.copy()\n        {\n            return null;\n        }\n\n        public List<FOLNode> getArgs()\n\t{\n\t    return new ReadOnlyCollection<Term>(terms).ToList<FOLNode>();\n\t}\n\n\tpublic Object accept(FOLVisitor v, Object arg)\n\t{\n\t    return v.visitTermEquality(this, arg);\n\t}\n\n\tpublic FOLNode copy()\n\t{\n\t    return new TermEquality((Term)term1.copy(), (Term)term2.copy());\n\t}\n\n        public Sentence copySentence()\n        {\n            return null;\n        }\n\n        // END-AtomicSentence\n\t\n\tpublic override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if ((o == null) || !(o is TermEquality))\n\t    {\n\t\treturn false;\n\t    }\n\t    TermEquality te = (TermEquality)o;\n\n\t    return te.getTerm1().Equals(term1) && te.getTerm2().Equals(term2);\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\n\t    if (0 == hashCode)\n\t    {\n\t\thashCode = 17;\n\t\thashCode = 37 * hashCode + getTerm1().GetHashCode();\n\t\thashCode = 37 * hashCode + getTerm2().GetHashCode();\n\t    }\n\t    return hashCode;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    if (null == stringRep)\n\t    {\n\t\tStringBuilder sb = new StringBuilder();\n\t\tsb.Append(term1.ToString());\n\t\tsb.Append(\" = \");\n\t\tsb.Append(term2.ToString());\n\t\tstringRep = sb.ToString();\n\t    }\n\t    return stringRep;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/fol/parsing/ast/Variable.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.fol.parsing;\n\nnamespace aima.core.logic.fol.parsing.ast\n{\n    /**\n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public class Variable : Term\n    {\n\tprivate String value;\n\tprivate int hashCode = 0;\n\tprivate int indexical = -1;\n\n\tpublic Variable(String s)\n\t{\n\t    value = s.Trim();\n\t}\n\n\tpublic Variable(String s, int idx)\n\t{\n\t    value = s.Trim();\n\t    indexical = idx;\n\t}\n\n\tpublic String getValue()\n\t{\n\t    return value;\n\t}\n\n\t// START-Term\n\n\tpublic String getSymbolicName()\n\t{\n\t    return getValue();\n\t}\n\n\tpublic bool isCompound()\n\t{\n\t    return false;\n\t}\n\n        List<FOLNode> FOLNode.getArgs()\n        {\n            return null;\n        }\n\n        public List<Term> getArgs()\n\t{\n\t    // Is not Compound, therefore should\n\t    // return null for its arguments\n\t    return null;\n\t}\n\n\tpublic Object accept(FOLVisitor v, Object arg)\n\t{\n\t    return v.visitVariable(this, arg);\n\t}\n\n        FOLNode FOLNode.copy()\n        {\n            return copy();\n        }\n\n        public Term copy()\n\t{\n\t    return new Variable(value, indexical);\n\t}\n\n\t// END-Term\n\n\tpublic int getIndexical()\n\t{\n\t    return indexical;\n\t}\n\n\tpublic void setIndexical(int idx)\n\t{\n\t    indexical = idx;\n\t    hashCode = 0;\n\t}\n\n\tpublic String getIndexedValue()\n\t{\n\t    return value + indexical;\n\t}\n\n\tpublic override bool Equals(Object o)\n\t{\n\n\t    if (this == o)\n\t    {\n\t\treturn true;\n\t    }\n\t    if (!(o is Variable))\n\t    {\n\t\treturn false;\n\t    }\n\n\t    Variable v = (Variable)o;\n\t    return v.getValue().Equals(getValue())\n\t\t    && v.getIndexical() == getIndexical();\n\t}\n\n\tpublic override int GetHashCode()\n\t{\n\t    if (0 == hashCode)\n\t    {\n\t\thashCode = 17;\n\t\thashCode += indexical;\n\t\thashCode = 37 * hashCode + value.GetHashCode();\n\t    }\n\n\t    return hashCode;\n\t}\n\n\tpublic override String ToString()\n\t{\n\t    return value;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/propositional/agent/KBAgent.cs",
    "content": "using aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.logic.propositional.kb;\nusing aima.core.logic.propositional.parsing.ast;\n\nnamespace aima.core.logic.propositional.agent\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 7.1, page\n     * 236.<br>\n     * <br>\n     * \n     * <pre>\n     * function KB-AGENT(percept) returns an action\n     *   persistent: KB, a knowledge base\n     *               t, a counter, initially 0, indicating time\n     *           \n     *   TELL(KB, MAKE-PERCEPT-SENTENCE(percept, t))\n     *   action &lt;- ASK(KB, MAKE-ACTION-QUERY(t))\n     *   TELL(KB, MAKE-ACTION-SENTENCE(action, t))\n     *   t &lt;- t + 1\n     *   return action\n     * \n     * </pre>\n     * \n     * Figure 7.1 A generic knowledge-based agent. Given a percept, the agent adds\n     * the percept to its knowledge base, asks the knowledge base for the best\n     * action, and tells the knowledge base that it has in fact taken that action.\n     * \n     * @author Ciaran O'Reilly\n     */\n    public abstract class KBAgent : AbstractAgent\n    {\n\t// persistent: KB, a knowledge base\n\tprotected KnowledgeBase KB;\n\t// t, a counter, initially 0, indicating time\n\tprivate int t = 0;\n\n\tpublic KBAgent(KnowledgeBase KB)\n\t{\n\t    this.KB = KB;\n\t}\n\n\t// function KB-AGENT(percept) returns an action\n\tpublic override Action execute(Percept percept)\n\t{\n\t    // TELL(KB, MAKE-PERCEPT-SENTENCE(percept, t))\n\t    KB.tell(makePerceptSentence(percept, t));\n\t    // action &lt;- ASK(KB, MAKE-ACTION-QUERY(t))\n\t    Action action = ask(KB, makeActionQuery(t));\n\n\t    // TELL(KB, MAKE-ACTION-SENTENCE(action, t))\n\t    KB.tell(makeActionSentence(action, t));\n\t    // t &lt;- t + 1\n\t    t = t + 1;\n\t    // return action\n\t    return action;\n\t}\n\n\t/**\n\t * MAKE-PERCEPT-SENTENCE constructs a sentence asserting that the agent\n\t * perceived the given percent at the given time.\n\t * \n\t * @param percept\n\t *            the given percept\n\t * @param t\n\t *            the given time\n\t * @return a sentence asserting that the agent perceived the given percept\n\t *         at the given time.\n\t */\n\t// MAKE-PERCEPT-SENTENCE(percept, t)\n\tpublic abstract Sentence makePerceptSentence(Percept percept, int t);\n\n\t/**\n\t * MAKE-ACTION-QUERY constructs a sentence that asks what action should be\n\t * done at the current time.\n\t * \n\t * @param t\n\t *            the current time.\n\t * @return a sentence that asks what action should be done at the current\n\t *         time.\n\t */\n\t// MAKE-ACTION-QUERY(t)\n\tpublic abstract Sentence makeActionQuery(int t);\n\n\t/**\n\t * MAKE-ACTION-SENTENCE constructs a sentence asserting that the chosen action was executed.\n\t * @param action\n\t *        the chose action.\n\t * @param t\n\t *        the time at which the action was executed.\n\t * @return a sentence asserting that the chosen action was executed.\n\t */\n\t// MAKE-ACTION-SENTENCE(action, t)\n\tpublic abstract Sentence makeActionSentence(Action action, int t);\n\n\t/**\n\t * A wrapper around the KB's ask() method which translates the action (in the form of\n\t * a sentence) determined by the KB into an allowed 'Action' object from the current\n\t * environment in which the KB-AGENT resides.\n\t * \n\t * @param KB\n\t *        the KB to ask.\n\t * @param actionQuery\n\t *        an action query.\n\t * @return the Action to be performed in response to the given query.\n\t */\n\t// ASK(KB, MAKE-ACTION-QUERY(t))\n\tpublic abstract Action ask(KnowledgeBase KB, Sentence actionQuery);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/propositional/kb/KnowledgeBase.cs",
    "content": "﻿using System;\nusing aima.core.logic.propositional.parsing.ast;\n\nnamespace aima.core.logic.propositional.kb\n{\n    public class KnowledgeBase\n    {\n        internal void tell(Sentence sentence)\n        {\n            throw new NotImplementedException();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/propositional/parsing/PLVisitor.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.logic.propositional.parsing.ast;\n\nnamespace aima.core.logic.propositional.parsing\n{\n    /**\n     * <b>Propositional Logic Visitor:</b> A <a\n     * href=\"http://en.wikipedia.org/wiki/Visitor_pattern\">Visitor Pattern/</a> for\n     * traversing the abstract syntax tree structural representation of\n     * propositional logic used in this library. The key difference between the\n     * default Visitor pattern and the code here, is that in the former the visit()\n     * methods have a void visit(ConcreteNode) signature while the visitors used\n     * here have a Object visit(ConcreteNode, Object arg) signature. This simplifies\n     * testing and allows some recursive code that is hard with the former .\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * \n     * @param <A>\n     *            the argument type to be passed to the visitor methods.\n     * @param <R>\n     *            the return type to be returned from the visitor methods.\n     */\n    public interface PLVisitor<A, R>\n    {\n\t/**\n\t * Visit a proposition symbol (e.g A).\n\t * \n\t * @param sentence\n\t *            a Sentence that is a propositional symbol.\n\t * @param arg\n\t *            optional argument to be used by the visitor.\n\t * @return optional return value to be used by the visitor.\n\t */\n\tR visitPropositionSymbol(PropositionSymbol sentence, A arg);\n\n\t/**\n\t * Visit a unary complex sentence (e.g. ~A).\n\t * \n\t * @param sentence\n\t *            a Sentence that is a unary complex sentence.\n\t * @param arg\n\t *            optional argument to be used by the visitor.\n\t * @return optional return value to be used by the visitor.\n\t */\n\tR visitUnarySentence(ComplexSentence sentence, A arg);\n\n\t/**\n\t * Visit a binary complex sentence (e.g. A & B).\n\t * \n\t * @param sentence\n\t *            a Sentence that is a binary complex sentence.\n\t * @param arg\n\t *            optional argument to be used by the visitor.\n\t * @return optional return value to be used by the visitor.\n\t */\n\tR visitBinarySentence(ComplexSentence sentence, A arg);\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/propositional/parsing/ast/AtomicSentence.cs",
    "content": "using System;\n\nnamespace aima.core.logic.propositional.parsing.ast\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 244.<br>\n     * <br>\n     * The <b>atomic sentences</b> consist of a single proposition symbol.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * \n     */\n    public abstract class AtomicSentence : Sentence\n    {\n\n    }\n}"
  },
  {
    "path": "aima-csharp/logic/propositional/parsing/ast/ComplexSentence.cs",
    "content": "﻿using aima.core.logic.propositional.parsing.ast;\nusing System;\n\nnamespace aima.core.logic.propositional.parsing.ast\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 244.<br>\n     * <br>\n     * <b>Complex Sentence:</b> are constructed from simpler sentences, using\n     * parentheses (and square brackets) and logical connectives.\n     *\n     * @author Ciaran O'Reilly\n     * @author Ravi Mohan \n     */\n    public class ComplexSentence : Sentence\n    {\n\n\n        private Connective connective;\n        private Sentence[] simplerSentences;\n        // Lazy initialize these values.\n        private int cachedHashCode = -1;\n        private String cachedConcreteSyntax = null;\n    \n        /**\n\t    * Constructor.\n\t    * \n\t    * @param connective\n\t    *            the complex sentence's connective.\n\t    * @param sentences\n\t    *            the simpler sentences making up the complex sentence.\n\t    */\n        public ComplexSentence(Connective connective, params Sentence[] sentences)\n        {\n            // Assertion checks\n            assertLegalArguments(connective, sentences);\n    \n            this.connective = connective;\n            simplerSentences = new Sentence[sentences.Length];\n            for (int i = 0; i < sentences.Length; i++)\n            {\n                simplerSentences[i] = sentences[i];\n            }\n        }\n    \n        /**\n\t    * Convenience constructor for binary sentences.\n\t    * \n\t    * @param sentenceL\n\t    * \t\t\tthe left hand sentence.\n\t    * @param binaryConnective\n\t    * \t\t\tthe binary connective.\n\t    * @param sentenceR\n\t    *  \t\tthe right hand sentence.\n\t    */\n        public ComplexSentence(Sentence sentenceL, Connective binaryConnective, Sentence sentenceR) : this(binaryConnective, sentenceL, sentenceR)\n        {\n            \n        }\n    \n        public override Connective getConnective()\n        {\n            return connective;\n        }\n    \n        public override int getNumberSimplerSentences()\n        {\n            return simplerSentences.Length;\n        }\n    \n        public override Sentence getSimplerSentence(int offset)\n        {\n            return simplerSentences[offset];\n        }\n    \n        public override bool Equals(Object o)\n        {\n            if (this == o)\n            {\n                return true;\n            }\n            if ((o == null) || (this.GetType() != o.GetType()))\n            {\n                return false;\n            }\n    \n            bool result = false;\n            ComplexSentence other = (ComplexSentence)o;\n            if (other.GetHashCode() == this.GetHashCode())\n            {\n                if (other.getConnective().Equals(this.getConnective())\n                        && other.getNumberSimplerSentences() == this\n                                .getNumberSimplerSentences())\n                {\n                    // connective and # of simpler sentences match\n                    // assume match and then test each simpler sentence\n                    result = true;\n                    for (int i = 0; i < this.getNumberSimplerSentences(); i++)\n                    {\n                        if (!other.getSimplerSentence(i).Equals(\n                                this.getSimplerSentence(i)))\n                        {\n                            result = false;\n                            break;\n                        }\n                    }\n                }\n            }\n    \n            return result;\n        }\n    \n        public override int GetHashCode()\n        {\n            if (cachedHashCode == -1)\n            {\n                cachedHashCode = 17 * getConnective().GetHashCode();\n                foreach(Sentence s in simplerSentences)\n                {\n                    cachedHashCode = (cachedHashCode * 37) + s.GetHashCode();\n                }\n            }\n    \n            return cachedHashCode;\n        }\n    \n        public override String ToString()\n        {\n            if (cachedConcreteSyntax == null)\n            {\n                if (isUnarySentence())\n                {\n                    cachedConcreteSyntax = getConnective()\n                            + bracketSentenceIfNecessary(getConnective(), getSimplerSentence(0));\n                }\n                else if (isBinarySentence())\n                {\n                    cachedConcreteSyntax = bracketSentenceIfNecessary(getConnective(), getSimplerSentence(0))\n                            + \" \"\n                            + getConnective()\n                            + \" \"\n                            + bracketSentenceIfNecessary(getConnective(), getSimplerSentence(1));\n                }\n            }\n            return cachedConcreteSyntax;\n        }\n    \n        //\n        // PRIVATE\n        //\n        private void assertLegalArguments(Connective connective, params Sentence[] sentences)\n        {\n            if (connective == null)\n            {\n                throw new ArgumentException(\"Connective must be specified.\");\n            }\n            if (sentences == null)\n            {\n                throw new ArgumentException(\"> 0 simpler sentences must be specified.\");\n            }\n            if (connective == Connective.NOT)\n            {\n                if (sentences.Length != 1)\n                {\n                    throw new ArgumentException(\"A not (~) complex sentence only take 1 simpler sentence not \" + sentences.Length);\n                }\n            }\n            else\n            {\n                if (sentences.Length != 2)\n                {\n                    throw new ArgumentException(\"Connective is binary (\" + connective + \") but only \" + sentences.Length + \" simpler sentences provided\");\n                }\n            }\n        }\n    }\n}\n        "
  },
  {
    "path": "aima-csharp/logic/propositional/parsing/ast/Connective.cs",
    "content": "﻿using System;\nusing aima.core.util;\nusing System.Collections.Generic;\n\nnamespace aima.core.logic.propositional.parsing.ast\n{\n    /**\n    * Artificial Intelligence A Modern Approach (3rd Edition): page 244.<br>\n    * <br>\n    * \n    * <pre>\n    * <b>Logical Connectives:</b> There are five connectives in common use:\n    * 1. ~   (not).\n    * 2. &   (and).\n    * 3. |   (or).\n    * 4. =>  (implication).\n    * 5. <=> (biconditional).\n    * \n    * Note: We use ASCII characters that commonly have the same meaning to those \n    * symbols used in the book.\n    * \n    * OPERATOR PRECEDENCE: ~, &, |, =>, <=>\n    * </pre>\n    * \n    * @author Ciaran O'Reilly\n    * @author Avinash Agarwal\n    * \n    */\n    public class Connective\n    {\n        public static readonly Connective NOT = new Connective(\"~\", 10);\n        public static readonly Connective AND = new Connective(\"&\", 8);\n        public static readonly Connective OR = new Connective(\"|\", 6);\n        public static readonly Connective IMPLICATION = new Connective(\"=>\", 4);\n        public static readonly Connective BICONDITIONAL = new Connective(\"<=>\", 2);\n\n        public static IEnumerable<Connective> Values\n        {\n            get\n            {\n                yield return NOT;\n                yield return AND;\n                yield return OR;\n                yield return IMPLICATION;\n                yield return BICONDITIONAL;\n            }\n        }\n\n        /**\n\t    * \n\t    * @return the symbol for this connective.\n\t    */\n        public String getSymbol()\n        {\n            return symbol;\n        }\n\n        /**\n         * \n         * @return the precedence associated with this connective.\n         */\n        public int getPrecedence()\n        {\n            return precedence;\n        }\n        \n        public String toString()\n        {\n            return getSymbol();\n        }\n\n        /**\n         * Determine if a given symbol is representative of a connective.\n         * \n         * @param symbol\n         *            a symbol to be tested whether or not is represents a\n         *            connective.\n         * @return true if the symbol passed in is representative of a connective.\n         */\n        public static bool isConnective(String symbol)\n        {\n            if (NOT.getSymbol().Equals(symbol))\n            {\n                return true;\n            }\n            else if (AND.getSymbol().Equals(symbol))\n            {\n                return true;\n            }\n            else if (OR.getSymbol().Equals(symbol))\n            {\n                return true;\n            }\n            else if (IMPLICATION.getSymbol().Equals(symbol))\n            {\n                return true;\n            }\n            else if (BICONDITIONAL.getSymbol().Equals(symbol))\n            {\n                return true;\n            }\n            return false;\n        }\n\n        /**\n         * Get the connective associated with the given symbolic representation.\n         * \n         * @param symbol\n         *            a symbol for which a corresponding connective is wanted.\n         * @return the connective associated with a given symbol.\n         * @throws IllegalArgumentException\n         *             if a connective cannot be found that matches the given\n         *             symbol.\n         */\n        public static Connective get(String symbol)\n        {\n            if (NOT.getSymbol().Equals(symbol))\n            {\n                return NOT;\n            }\n            else if (AND.getSymbol().Equals(symbol))\n            {\n                return AND;\n            }\n            else if (OR.getSymbol().Equals(symbol))\n            {\n                return OR;\n            }\n            else if (IMPLICATION.getSymbol().Equals(symbol))\n            {\n                return IMPLICATION;\n            }\n            else if (BICONDITIONAL.getSymbol().Equals(symbol))\n            {\n                return BICONDITIONAL;\n            }\n\n            throw new ArgumentException(\n                    \"Not a valid symbol for a connective: \" + symbol);\n        }\n\n        /**\n         * Determine if the given character is at the beginning of a connective.\n         * \n         * @param ch\n         *            a character.\n         * @return true if the given character is at the beginning of a connective's\n         *         symbolic representation, false otherwise.\n         */\n        public static bool isConnectiveIdentifierStart(char ch)\n        {\n            return _connectiveLeadingChars.Contains(ch);\n        }\n\n        /**\n         * Determine if the given character is part of a connective.\n         * \n         * @param ch\n         *            a character.\n         * @return true if the given character is part of a connective's symbolic\n         *         representation, false otherwise.\n         */\n        public static bool isConnectiveIdentifierPart(char ch)\n        {\n            return _connectiveChars.Contains(ch);\n        }\n\n        //\n        // PRIVATE\n        //\n        private static readonly HashSet<char> _connectiveLeadingChars = Util.createSet('~', '&', '|', '=', '<');\n        private static readonly HashSet<char> _connectiveChars        = Util.createSet('~', '&', '|', '=', '<', '>');\n\n        private readonly int precedence;\n        private readonly String symbol;\n\n        private Connective(String symbol, int precedence)\n        {\n            this.precedence = precedence;\n            this.symbol = symbol;\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "aima-csharp/logic/propositional/parsing/ast/PropositionSymbol.cs",
    "content": "﻿using System;\nusing System.CodeDom.Compiler;\n\nnamespace aima.core.logic.propositional.parsing.ast\n{\n    /**\n    * Artificial Intelligence A Modern Approach(3rd Edition): page 244.<br>\n    * <br>\n    * <b>Proposition Symbol:</b> Each such symbol stands for a proposition that can\n    * be true or false. There are two proposition symbols with fixed meanings:\n    * < i > True </ i > the always - true proposition and < i > False </ i > the always - false\n    * proposition.< br >\n    * < br >\n    * < b > Note </ b >: While the book states:< br >\n    * 'We use symbols that start with an upper case letter and may contain other\n    * letters or subscripts'. In this implementation we allow any legal java\n    * identifier to stand in for a proposition symbol.\n    *\n    * @author Ciaran O'Reilly\n    * @author Ravi Mohan\n    *\n    * @see SourceVersion#isIdentifier(CharSequence)\n    */\n\n    public class PropositionSymbol : AtomicSentence\n    {\n        public static readonly String TRUE_SYMBOL  = \"True\";\n\t    public static readonly String FALSE_SYMBOL = \"False\";\n\t    public static readonly PropositionSymbol TRUE  = new PropositionSymbol(TRUE_SYMBOL);\n        public static readonly PropositionSymbol FALSE = new PropositionSymbol(FALSE_SYMBOL);\n        //\n        private String symbol;\n\n        /**\n         * Constructor.\n         * \n         * @param symbol\n         *            the symbol uniquely identifying the proposition.\n         */\n        public PropositionSymbol(String symbol)\n        {\n            // Ensure differing cases for the 'True' and 'False'\n            // propositional constants are represented in a canonical form.\n            if (TRUE_SYMBOL.ToLower().Equals(symbol.ToLower()))\n            {\n                this.symbol = TRUE_SYMBOL;\n            }\n            else if (FALSE_SYMBOL.ToLower().Equals(symbol.ToLower()))\n            {\n                this.symbol = FALSE_SYMBOL;\n            }\n            else if (isPropositionSymbol(symbol))\n            {\n                this.symbol = symbol;\n            }\n            else\n            {\n                throw new ArgumentException(\"Not a legal proposition symbol: \" + symbol);\n            }\n        }\n\n        /**\n         * \n         * @return true if this is the always 'True' proposition symbol, false\n         *         otherwise.\n         */\n        public bool isAlwaysTrue()\n        {\n            return TRUE_SYMBOL.Equals(symbol);\n        }\n\n        /**\n         * \n         * @return true if the symbol passed in is the always 'True' proposition\n         *         symbol, false otherwise.\n         */\n        public static bool isAlwaysTrueSymbol(String symbol)\n        {\n            return TRUE_SYMBOL.ToLower().Equals(symbol.ToLower());\n        }\n\n        /**\n         * \n         * @return true if this is the always 'False' proposition symbol, false\n         *         other.\n         */\n        public bool isAlwaysFalse()\n        {\n            return FALSE_SYMBOL.Equals(symbol);\n        }\n\n        /**\n         * \n         * @return true if the symbol passed in is the always 'False' proposition\n         *         symbol, false other.\n         */\n        public static bool isAlwaysFalseSymbol(String symbol)\n        {\n            return FALSE_SYMBOL.ToLower().Equals(symbol.ToLower());\n        }\n\n        /**\n         * Determine if the given symbol is a legal proposition symbol.\n         * \n         * @param symbol\n         *            a symbol to be tested.\n         * @return true if the given symbol is a legal proposition symbol, false\n         *         otherwise.\n         */\n        public static bool isPropositionSymbol(String symbol)\n        {\n            CodeDomProvider provider = CodeDomProvider.CreateProvider(\"C#\");\n            return provider.IsValidIdentifier(symbol);\n        }\n\n        /**\n         * Determine if the given character can be at the beginning of a proposition\n         * symbol.\n         * \n         * @param ch\n         *            a character.\n         * @return true if the given character can be at the beginning of a\n         *         proposition symbol representation, false otherwise.\n         */\n        public static bool isPropositionSymbolIdentifierStart(char ch)\n        {\n            CodeDomProvider provider = CodeDomProvider.CreateProvider(\"C#\");\n            return provider.IsValidIdentifier(ch.ToString());\n        }\n\n        /**\n         * Determine if the given character is part of a proposition symbol.\n         * \n         * @param ch\n         *            a character.\n         * @return true if the given character is part of a proposition symbols\n         *         representation, false otherwise.\n         */\n        public static bool isPropositionSymbolIdentifierPart(char ch)\n        {\n            CodeDomProvider provider = CodeDomProvider.CreateProvider(\"C#\");\n            return provider.IsValidIdentifier(\"a\"+ch);\n        }\n\n        /**\n         * \n         * @return the symbol uniquely identifying the proposition.\n         */\n        public String getSymbol()\n        {\n            return symbol;\n        }\n\n        public override bool Equals(Object o)\n        {\n\n            if (this == o)\n            {\n                return true;\n            }\n            if ((o == null) || (this.GetType() != o.GetType()))\n            {\n                return false;\n            }\n            PropositionSymbol sym = (PropositionSymbol)o;\n            return symbol.Equals(sym.symbol);\n\n        }\n\n        \n        public override int GetHashCode()\n        {\n            return symbol.GetHashCode();\n        }\n\n        public override String ToString()\n        {\n            return getSymbol();\n        }\n    }\n}\n"
  },
  {
    "path": "aima-csharp/logic/propositional/parsing/ast/Sentence.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing aima.core.logic.common;\nusing aima.core.logic.propositional.parsing;\nusing aima.core.util;\n\nnamespace aima.core.logic.propositional.parsing.ast\n{\n    /**\n    * Artificial Intelligence A Modern Approach (3rd Edition): page 244.<br>\n    * <br>\n    * The base of the knowledge representation language for propositional logic.\n    * Note: this class hierarchy defines the abstract syntax representation used\n    * for representing propositional logic.\n    * \n    * @author Ciaran O'Reilly\n    * @author Ravi Mohan\n    * @author Avinash Agarwal\n    * \n    */\n\n    public abstract class Sentence : ParseTreeNode\n    {\n        /**\n\t    * \n\t    * @return the logical connective associated with this sentence if it has\n\t    *         one (i.e. is a ComplexSentence), null otherwise.\n\t    */\n        public virtual Connective getConnective()\n        {\n            return null;\n        }\n\n        /**\n\t     * \n\t     * @return the number of simpler sentences contained in this sentence. Will\n\t     *         only be > 0 if a Complex Sentence.\n\t     */\n        public virtual int getNumberSimplerSentences()\n        {\n            return 0;\n        }\n\n        /**\n         * Get the simplified sentence, at the specified offset (starts at 0),\n         * contained by this Sentence if it is a Complex Sentence, null otherwise.\n         * \n         * @param offset\n         *            the offset of the contained simplified sentence to retrieve.\n         * @return the simplified sentence, at the specified offset, contained by\n         *         this sentence (if a complex sentence), null otherwise.\n         */\n        public virtual Sentence getSimplerSentence(int offset)\n        {\n            return null;\n        }\n\n        /**\n         * \n         * @return true if a complex sentence with a Not connective, false\n         *         otherwise.\n         */\n        public bool isNotSentence()\n        {\n            return hasConnective(Connective.NOT);\n        }\n\n        /**\n         * \n         * @return true if a complex sentence with an And connective, false\n         *         otherwise.\n         */\n        public bool isAndSentence()\n        {\n            return hasConnective(Connective.AND);\n        }\n\n        /**\n         * \n         * @return true if a complex sentence with an Or connective, false\n         *         otherwise.\n         */\n        public bool isOrSentence()\n        {\n            return hasConnective(Connective.OR);\n        }\n\n        /**\n         * \n         * @return true if a complex sentence with an Implication connective, false\n         *         otherwise.\n         */\n        public bool isImplicationSentence()\n        {\n            return hasConnective(Connective.IMPLICATION);\n        }\n\n        /**\n         * \n         * @return true if a complex sentence with a Biconditional connective, false\n         *         otherwise.\n         */\n        public bool isBiconditionalSentence()\n        {\n            return hasConnective(Connective.BICONDITIONAL);\n        }\n\n        /**\n         * \n         * @return true if a proposition symbol, false otherwise.\n         */\n        public bool isPropositionSymbol()\n        {\n            return getConnective() == null;\n        }\n\n        /**\n         * \n         * @return true if a complex sentence containing a single simpler sentence,\n         *         false otherwise.\n         */\n        public bool isUnarySentence()\n        {\n            return hasConnective(Connective.NOT);\n        }\n\n        /**\n         * \n         * @return true if a complex sentence containing two simpler sentences,\n         *         false otherwise.\n         */\n        public bool isBinarySentence()\n        {\n            return getConnective() != null && !hasConnective(Connective.NOT);\n        }\n\n        /**\n         * Allow a PLVisitor to walk over the abstract syntax tree represented by this\n         * Sentence.\n         * \n         * @param plv\n         *            a Propositional Logic visitor.\n         * @param arg\n         *            an optional argument for use by the visior.\n         * @return a result specific to the visitors behavior.\n         */\n        public R accept<A, R>(PLVisitor<A, R> plv, A arg)\n        {\n            R result = default(R);\n            if (isPropositionSymbol())\n            {\n                result = plv.visitPropositionSymbol((PropositionSymbol)this, arg);\n            }\n            else if (isUnarySentence())\n            {\n                result = plv.visitUnarySentence((ComplexSentence)this, arg);\n            }\n            else if (isBinarySentence())\n            {\n                result = plv.visitBinarySentence((ComplexSentence)this, arg);\n            }\n\n            return result;\n        }\n\n        /**\n         * Utility routine that will create a string representation of a given\n         * Sentence and place it inside brackets if it is a complex sentence that\n         * has lower precedence than this complex sentence.<br>\n         * <br>\n         * Note: this is a form of pretty printing, whereby we only add brackets in\n         * the concrete syntax representation as needed to ensure it can be parsed\n         * back again into an equivalent abstract syntax representation used here.\n         * \n         * @param parentConnective\n         *            the connective of the parent sentence.\n         * @param childSentence\n         *            a simpler child sentence.\n         * @return a String representation of the Sentence, bracketed if the parent\n         *         based on its connective has higher precedence.\n         */\n        public String bracketSentenceIfNecessary(Connective parentConnective,\n                Sentence childSentence)\n        {\n            String result = null;\n            if (childSentence is ComplexSentence) {\n                ComplexSentence cs = (ComplexSentence)childSentence;\n                if (cs.getConnective().getPrecedence() < parentConnective\n                        .getPrecedence())\n                {\n                    result = \"(\" + childSentence + \")\";\n                }\n            }\n\n            if (result == null)\n            {\n                result = childSentence.ToString();\n            }\n\n            return result;\n        }\n\n        /**\n         * Create a disjunction of disjuncts.\n         * @param disjuncts\n         * \t\t\tthe disjuncts from which to create the disjunction.\n         * @return a disjunction of the given disjuncts.\n         */\n        public static Sentence newDisjunction(params Sentence[] disjuncts)\n        {\n            return newDisjunction(disjuncts.ToList());\n        }\n\n        /**\n         * Create a disjunction of disjuncts.\n         * @param disjuncts\n         * \t\t\tthe disjuncts from which to create the disjunction.\n         * @return a disjunction of the given disjuncts.\n         */\n        public static Sentence newDisjunction(List<Sentence> disjuncts)\n        {\n            if (disjuncts.Count == 0)\n            {\n                return PropositionSymbol.FALSE;\n            }\n            else if (disjuncts.Count == 1)\n            {\n                return disjuncts[0];\n            }\n            return new ComplexSentence(Util.first(disjuncts), Connective.OR, newDisjunction(Util.rest(disjuncts)));\n        }\n\n        /**\n         * Create a conjunction of conjuncts.\n         * @param conjuncts\n         * \t\t\tthe conjuncts from which to create the conjunction.\n         * @return a conjunction of the given conjuncts.\n         */\n        public static Sentence newConjunction(params Sentence[] conjuncts)\n        {\n            return newConjunction(conjuncts.ToList());\n        }\n\n        /**\n         * Create a conjunction of conjuncts.\n         * @param conjuncts\n         * \t\t\tthe conjuncts from which to create the conjunction.\n         * @return a conjunction of the given conjuncts.\n         */\n        public static Sentence newConjunction(List<Sentence> conjuncts)\n        {\n            if (conjuncts.Count == 0)\n            {\n                return PropositionSymbol.TRUE;\n            }\n            else if (conjuncts.Count == 1)\n            {\n                return conjuncts[0];\n            }\n            return new ComplexSentence(Util.first(conjuncts), Connective.AND, newConjunction(Util.rest(conjuncts)));\n        }\n        \n        // PROTECTED\n\n        protected bool hasConnective(Connective connective)\n        {\n            // Note: can use '==' as Connective is an enum.\n            return getConnective() == connective;\n        }\n    }\n}\n"
  },
  {
    "path": "aima-csharp/search/Local/FitnessFunction.cs",
    "content": "namespace aima.core.search.local\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 127.<br>\n     * <br>\n     * Each state is rated by the objective function, or (in Genetic Algorithm\n     * terminology) the fitness function. A fitness function should return higher\n     * values for better states.\n     * <br>\n     * Here, we assume that all values are greater or equal to zero.\n     * \n     * @author Ciaran O'Reilly\n     * \n     * @param <A>\n     *            the type of the alphabet used in the representation of the\n     *            individuals in the population (this is to provide flexibility in\n     *            terms of how a problem can be encoded).\n     */\n    public interface FitnessFunction<A>\n    {\n        /**\n         * \n         * @param individual\n         *            the individual whose fitness is to be accessed.\n         * @return the individual's fitness value (the higher the better).\n         */\n        double apply(Individual<A> individual);\n    }\n}"
  },
  {
    "path": "aima-csharp/search/Local/Individual.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.search.local\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 127.<br>\n     * <br>\n     * A state in a genetic algorithm is represented as an individual from the\n     * population.\n     * \n     * @author Ciaran O'Reilly\n     * \n     * @param <A>\n     *            the type of the alphabet used in the representation of the\n     *            individuals in the population (this is to provide flexibility in\n     *            terms of how a problem can be encoded).\n     */\n     public class Individual<A>\n    {\n        private List<A> representation = new List<A>();\n        private int descendants; // for debugging\n        \n        /**\n\t * Construct an individual using the provided representation.\n\t * \n    \t * @param representation\n    \t *            the individual's representation.\n    \t */\n        public Individual(List<A> representation)\n        {\n            this.representation = representation;\n        }\n\n        /**\n\t * \n\t * @return the individual's representation.\n\t */\n        public List<A> getRepresentation()\n        {\n            return representation;\n        }\n\n        /**\n    \t * \n    \t * @return the length of the individual's representation.\n    \t */\n        public int length()\n        {\n            return representation.Count;\n        }\n\n        /**\n\t * Should be called by the genetic algorithm whenever the individual is\n\t * selected to produce a descendant.\n\t */\n        public void incDescendants()\n        {\n            descendants++;\n        }\n\n        // Returns the number of descendants for this individual.\n        public int getDescendants()\n        {\n            return descendants;\n        }\n\n        public String toString()\n        {            \n            return representation.ToString() + descendants;            \n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/Local/Scheduler.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.search.local\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n     public class Scheduler\n    {\n        private int k, limit;\n        private double lam;\n\n        public Scheduler(int k, double lam, int limit)\n        {\n            this.k = k;\n            this.lam = lam;\n            this.limit = limit;\n        }\n\n        public Scheduler()\n        {\n            this.k = 20;\n            this.lam = 0.045;\n            this.limit = 100;\n        }\n\n        public double getTemp(int t)\n        {\n            if (t < limit)\n            {\n                double res = k * Math.Exp((-1) * lam * t);\n                return res;\n            }\n            else\n            {\n                return 0.0;\n            }\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/CutOffIndicatorAction.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent.impl;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * A NoOp action that indicates a CutOff has occurred in a search. Used\n     * primarily by DepthLimited and IterativeDeepening search routines.\n     * \n     * @author Ciaran O'Reilly\n     */\n    public class CutOffIndicatorAction : DynamicAction\n    {\n        public static readonly CutOffIndicatorAction CUT_OFF = new CutOffIndicatorAction();\n\n        // START-Action\n        public bool isNoOp()\n        {\n            return true;\n        }\n\n        // END-Action\n        private CutOffIndicatorAction(): base(\"CutOff\")\n        {\n\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/EvaluationFunction.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 92.<br>\n     * <br>\n     * The evaluation function is construed as a cost estimate, so the node with the\n     * lowest evaluation is expanded first.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface EvaluationFunction\n    {\n        double f(Node n);\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/HeuristicFunction.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 92.<br>\n     * <br>\n     * a heuristic function, denoted h(n):<br>\n     * h(n) = estimated cost of the cheapest path from the state at node n to a goal\n     * state.<br>\n     * <br>\n     * Notice that h(n) takes a node as input, but, unlike g(n) it depends only on\n     * the state at that node.\n     * \n     * @author Ravi Mohan\n     * \n     */\n     public interface HeuristicFunction\n    {\n        double h(Object state);\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/Metrics.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * Stores key-value pairs for efficiency analysis.\n     * \n     * @author Ravi Mohan\n     * @author Ruediger Lunde\n     */\n     public class Metrics\n    {\n        private Dictionary<String, String> hash;\n\n        public Metrics()\n        {\n            this.hash = new Dictionary<String, String>();\n        }\n\n        public void set(String name, int i)\n        {\n            hash[name] = i.ToString();\n        }\n\n        public void set(String name, double d)\n        {\n            hash[name] = d.ToString();\n        }\n\n        public void incrementInt(String name)\n        {\n            set(name, getInt(name) + 1);\n        }\n\n        public void set(String name, long l)\n        {\n            hash[name] = l.ToString();\n        }\n\n        public int getInt(String name)\n        {\n            return int.Parse(hash[name]);\n        }\n\n        public double getDouble(String name)\n        {\n            return double.Parse(hash[name]);\n        }\n\n        public long getLong(String name)\n        {\n            return long.Parse(hash[name]);\n        }\n\n        public String get(String name)\n        {\n            return hash[name];\n        }\n\n        public HashSet<String> keySet()\n        {\n            return new HashSet<string>(hash.Keys);\n        }\n\n        public String toString()\n        {\n            SortedDictionary<String, String> map = new SortedDictionary<String, String>(hash);\n            return map.ToString();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/Node.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Action = aima.core.agent.Action;\n\nnamespace aima.core.search.framework\n{\n    /// <summary>\n    ///     Represents a node in a search tree which corresponds to a state in a state space.\n    /// </summary>\n    /// <remarks>\n    ///     Artificial Intelligence A Modern Approach (3rd Edition): Figure 3.10, page 79.\n    ///     - Nodes are the data structures from which the search tree is constructed.\n    ///     - Each node has a parent, a state, and various bookkeeping fields.\n    ///     - Arrows point from child to parent.\n    ///     <para />\n    ///     @author Ravi Mohan\n    ///     @author Ciaran O'Reilly\n    ///     @author Mike Stampone\n    /// </remarks>\n    public class Node\n    {\n        /// <summary>\n        ///     The action that was applied to the parent to generate this node.\n        /// </summary>\n        public Action Action { get; }\n\n        /// <summary>\n        ///     The node in the search tree that generated this node.\n        /// </summary>\n        public Node Parent { get; }\n\n        /// <summary>\n        ///     The cumulative cost, traditionally denoted by g(n), of the path from the initial state to this node (as indicated by the parent pointers).\n        /// </summary>\n        public double PathCost { get; }\n\n        /// <summary>\n        ///     The state in the state space to which this node corresponds.\n        /// </summary>\n        public object State { get; }\n\n        /// <summary>\n        ///     Creates a new instance of <see cref=\"Node\" /> with the specified state.\n        /// </summary>\n        public Node(object state)\n        {\n            if (state == null)\n            {\n                throw new ArgumentNullException(nameof(state));\n            }\n\n            State = state;\n            PathCost = 0.0;\n        }\n\n        /// <summary>\n        ///     Creates a new instance of <see cref=\"Node\" /> with the specified state, parent, action, and step cost.\n        ///     <para>\n        ///         The step cost is the cost from the parent node to this node.\n        ///     </para>\n        /// </summary>\n        public Node(object state, Node parent, Action action, double stepCost) : this(state)\n        {\n            if (parent == null)\n            {\n                throw new ArgumentNullException(nameof(parent));\n            }\n            if (action == null)\n            {\n                throw new ArgumentNullException(nameof(action));\n            }\n\n            Parent = parent;\n            Action = action;\n            PathCost = parent.PathCost + stepCost;\n        }\n\n        /// <summary>\n        ///     Returns the path from the root node to this node.\n        /// </summary>\n        public List<Node> GetPathFromRoot()\n        {\n            var path = new List<Node>();\n            var current = this;\n\n            while (true)\n            {\n                path.Insert(0, current);\n\n                if (current.IsRoot())\n                {\n                    break;\n                }\n\n                current = current.Parent;\n            }\n\n            return path;\n        }\n\n        /// <summary>\n        ///     Returns <see langword=\"true\" /> if this node has no parent node; otherwise, <see langword=\"false\" />.\n        /// </summary>\n        public bool IsRoot()\n        {\n            return Parent == null;\n        }\n\n        public override string ToString()\n        {\n            return string.Join(\" <-- \", GetPathFromRoot().Select(x => $\"[action={Action}, state={State}, pathCost={PathCost}]\"));\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/NodeExpander.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * Instances of this class are responsible for node creation and expansion. They\n     * compute path costs, support progress tracing, and count the number of\n     * {@link #expand(Node, Problem)} calls.\n     * \n     * @author Ruediger Lunde\n     *\n     */\n    public class NodeExpander\n    {\n        // expanding nodes\n\n        public Node createRootNode(System.Object state)\n        {\n            return new Node(state);\n        }\n\n        /**\n\t * Computes the path cost for getting from the root node state via the\n\t * parent node state to the specified state, creates a new node for the\n\t * specified state, adds it as child of the provided parent, and returns it.\n\t */\n         public Node createNode(System.Object state, Node parent, Action action, double stepCost)\n        {\n            return new Node(state, parent, action, parent.PathCost + stepCost);\n        }\n\n        /**\n\t * Returns the children obtained from expanding the specified node in the\n    \t * specified problem.\n    \t * \n    \t * @param node\n    \t *            the node to expand\n    \t * @param problem\n    \t *            the problem the specified node is within.\n    \t * \n    \t * @return the children obtained from expanding the specified node in the\n    \t *         specified problem.\n    \t */\n        public List<Node> expand(Node node, Problem problem)\n        {\n            List<Node> successors = new List<Node>();\n\n            ActionsFunction actionsFunction = problem.getActionsFunction();\n            ResultFunction resultFunction = problem.getResultFunction();\n            StepCostFunction stepCostFunction = problem.getStepCostFunction();\n\n            foreach (Action action in actionsFunction.actions(node.State))\n            {\n                System.Object successorState = resultFunction.result(node.State, action);\n\n                double stepCost = stepCostFunction.c(node.State, action, successorState);\n                successors.Add(createNode(successorState, node, action, stepCost));\n            }\n\n            foreach (NodeListener listener in nodeListeners)\n            {\n                listener.onNodeExpanded(node);\n            }\n            counter++;\n            return successors;\n        }\n\n        // progress tracing and statistical data\n\n        /** Interface for progress Tracers */\n        public interface NodeListener\n        {\n            void onNodeExpanded(Node node);\n        }\n\n        /**\n\t * All node listeners added to this list get informed whenever a node is\n\t * expanded.\n\t */\n        private List<NodeListener> nodeListeners = new List<NodeListener>();\n\n        /** Counts the number of {@link #expand(Node, Problem)} calls. */\n        private int counter;\n\n        /**\n    \t * Adds a listener to the list of node listeners. It is informed whenever a\n\t * node is expanded during search.\n\t */\n        public void addNodeListener(NodeListener listener)\n        {\n            nodeListeners.Add(listener);\n        }\n\n        /**\n    \t * Resets the counter for {@link #expand(Node, Problem)} calls.\n    \t */\n        public void resetCounter()\n        {\n            counter = 0;\n        }\n\n        /**\n\t * Returns the number of {@link #expand(Node, Problem)} calls since the last\n\t * counter reset.\n\t */\n        public int getNumOfExpandCalls()\n        {\n            return counter;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/PathCostFunction.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.search.framework\n{    \n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 78.<br>\n     * <br>\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class PathCostFunction\n    {\n        public PathCostFunction()\n        {\n\n        }\n\n        /**\n         * \n         * @param n\n         * @return the cost, traditionally denoted by g(n), of the path from the\n         *         initial state to the node, as indicated by the parent pointers.\n         */\n        public double g(Node n)\n        {\n            return n.PathCost;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/PerceptToStateFunction.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * This interface is to define how to Map a Percept to a State representation\n     * for a problem solver within a specific environment. This arises in the\n     * description of the Online Search algorithms from Chapter 4.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n     public interface PerceptToStateFunction\n    {\n        /**\n\t * Get the problem state associated with a Percept.\n\t * \n\t * @param p\n\t *            the percept to be transformed to a problem state.\n\t * @return a problem state derived from the Percept p.\n\t */\n        Object getState(Percept p);\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/Search.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework\n{\n\n    /**\n     * @author Ravi Mohan\n     * @author Mike Stampone\n     */\n    public interface Search\n    {\n        /**\n\t * Returns a list of actions to the goal if the goal was found, a list\n\t * containing a single NoOp Action if already at the goal, or an empty list\n\t * if the goal could not be found.\n\t * \n\t * @param p\n\t *            the search problem\n\t * \n\t * @return a list of actions to the goal if the goal was found, a list\n\t *         containing a single NoOp Action if already at the goal, or an\n\t *         empty list if the goal could not be found.\n\t */\n        List<Action> search(Problem p);\n\n        /**\n\t * Returns all the metrics of the search.\n\t * \n\t * @return all the metrics of the search.\n\t */\n        Metrics getMetrics();\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/SearchAgent.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n     public class SearchAgent : AbstractAgent\n    {\n        protected List<Action> actionList;\n\n        private List<Action>.Enumerator actionIterator;\n\n        private Metrics searchMetrics;\n\n        public SearchAgent(Problem p, Search search)\n        {\n            actionList = search.search(p);\n            actionIterator = actionList.GetEnumerator();\n            searchMetrics = search.getMetrics();\n        }\n\n        public override Action execute(Percept p)\n        {\n\n            if (actionIterator.MoveNext())\n            {\n                return actionIterator.Current;\n            }\n            else\n            {\n                return NoOpAction.NO_OP;\n            }\n        }\n\n        public bool isDone()\n        {\n            return null != actionIterator.Current;\n        }\n\n        public List<Action> getActions()\n        {\n            return actionList;\n        }\n\n        public Dictionary<string, string> getInstrumentation()\n        {\n            Dictionary<string, string> retVal = new Dictionary<string, string>();\n            foreach (string key in searchMetrics.keySet())\n            {\n                System.String value = searchMetrics.get(key);\n                retVal.Add(key, value);\n            }\n            return retVal;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/SearchForActions.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * Interface for all search algorithms which store at least a part of the\n     * exploration history as search tree and return a list of actions which lead\n     * from the initial state to a goal state.\n     * \n     * @author Ruediger Lunde\n     *\n     */\n    public interface SearchForActions : Search\n    {\n        NodeExpander getNodeExpander();\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/SearchUtils.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * Provides several useful static methods for implementing search.\n     * \n     * @author Ravi Mohan\n     * @author Ruediger Lunde\n     * \n     */\n     public class SearchUtils\n    {\n        /**\n\t * Returns the list of actions corresponding to the complete path to the\n\t * given node or NoOp if path length is one.\n\t */    \n        public static List<Action> getSequenceOfActions(Node node)\n        {\n            List<Node> nodes = node.GetPathFromRoot();\n            List<Action> actions = new List<Action>();\n\n            if(nodes.Count == 1)\n            {\n                // I'm at the root node, this indicates I started at the\n                // Goal node, therefore just return a NoOp\n                actions.Add(NoOpAction.NO_OP);\n            }\n            else\n            {\n                // ignore the root node this has no action\n                // hence index starts from 1 not zero\n                for (int i = 1; i < nodes.Count; i++)\n                {\n                    Node node_temp = nodes[i];\n                    actions.Add(node_temp.Action);\n                }\n            }\n            return actions;\n        }\n\n        /** Returns an empty action list. */\n        public static List<Action> failure()\n        {\n            return new List<Action>();\n        }\n\n        /** Checks whether a list of actions is empty. */\n        public static bool isFailure(List<Action> actions)\n        {\n            if(actions.Count == 0)\n            {\n                return true;\n            }\n            else\n            {\n                return false;\n            }      \n\n        }\n        \n\n        /**\n\t * Calls the goal test of the problem and - if the goal test is effectively\n\t * a {@link SolutionChecker} - additionally checks, whether the solution is\n\t * acceptable. Solution checkers can be used to analyze several or all\n\t * solutions with only one search run.\n\t */\n        public static bool isGoalState(Problem p, Node n)\n        {\n            bool isGoal = false;\n            GoalTest gt = p.getGoalTest();\n            if (gt.isGoalState(n.State))\n            {\n                if (gt is SolutionChecker)\n                {\n                    isGoal = ((SolutionChecker)gt).isAcceptableSolution(\n                            getSequenceOfActions(n), n.State);\n                }\n                else\n                {\n                    isGoal = true;\n                }\n            }\n            return isGoal;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/SimpleProblemSolvingAgent.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.util;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 3.1, page 67.<br>\n     * <br>\n     * \n     * <pre>\n     * function SIMPLE-PROBLEM-SOLVING-AGENT(percept) returns an action\n     *   persistent: seq, an action sequence, initially empty\n     *               state, some description of the current world state\n     *               goal, a goal, initially null\n     *               problem, a problem formulation\n     *           \n     *   state &lt;- UPDATE-STATE(state, percept)\n     *   if seq is empty then\n     *     goal    &lt;- FORMULATE-GOAL(state)\n     *     problem &lt;- FORMULATE-PROBLEM(state, goal)\n     *     seq     &lt;- SEARCH(problem)\n     *     if seq = failure then return a null action\n     *   action &lt;- FIRST(seq)\n     *   seq &lt;- REST(seq)\n     *   return action\n     * </pre>\n     * \n     * Figure 3.1 A simple problem-solving agent. It first formulates a goal and a\n     * problem, searches for a sequence of actions that would solve the problem, and\n     * then executes the actions one at a time. When this is complete, it formulates\n     * another goal and starts over.<br>\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n     public abstract class SimpleProblemSolvingAgent : AbstractAgent\n    {\n\n        // seq, an action sequence, initially empty\n        private List<Action> seq = new List<Action>();\n\n        //\n        private bool formulateGoalsIndefinitely = true;\n\n        private int maxGoalsToFormulate = 1;\n\n        private int goalsFormulated = 0;\n\n        /**\n\t * Constructs a simple problem solving agent which will formulate goals\n    \t * indefinitely.\n    \t */\n         public SimpleProblemSolvingAgent()\n        {\n            formulateGoalsIndefinitely = true;\n        }\n\n        /**\n    \t * Constructs a simple problem solving agent which will formulate, at\n    \t * maximum, the specified number of goals.\n    \t * \n    \t * @param maxGoalsToFormulate\n    \t *            the maximum number of goals this agent is to formulate.\n\t */\n         public SimpleProblemSolvingAgent(int maxGoalsToFormulate)\n        {\n            formulateGoalsIndefinitely = false;\n            this.maxGoalsToFormulate = maxGoalsToFormulate;\n        }\n\n        // function SIMPLE-PROBLEM-SOLVING-AGENT(percept) returns an action\n        public override Action execute(Percept p)\n        {\n            Action action = NoOpAction.NO_OP;\n\n            // state <- UPDATE-STATE(state, percept)\n            updateState(p);\n            // if seq is empty then do\n            if (0 == seq.Count)\n            {\n                if (formulateGoalsIndefinitely\n                        || goalsFormulated < maxGoalsToFormulate)\n                {\n                    if (goalsFormulated > 0)\n                    {\n                        notifyViewOfMetrics();\n                    }\n                    // goal <- FORMULATE-GOAL(state)\n                    System.Object goal = formulateGoal();\n                    goalsFormulated++;\n                    // problem <- FORMULATE-PROBLEM(state, goal)\n                    Problem problem = formulateProblem(goal);\n                    // seq <- SEARCH(problem)\n                    seq.AddRange(search(problem));\n                    if (0 == seq.Count)\n                    {\n                        // Unable to identify a path\n                        seq.Add(NoOpAction.NO_OP);\n                    }\n                }\n                else\n                {\n                    // Agent no longer wishes to\n                    // achieve any more goals\n                    setAlive(false);\n                    notifyViewOfMetrics();\n                }\n            }\n\n            if (seq.Count > 0)\n            {\n                // action <- FIRST(seq)\n                action = Util.first(seq);\n                // seq <- REST(seq)\n                seq = Util.rest(seq);\n            }\n\n            return action;\n        }\n\n        // PROTECTED METHODS\n        \n        protected abstract State updateState(Percept p);\n\n        protected abstract System.Object formulateGoal();\n\n        protected abstract Problem formulateProblem(System.Object goal);\n\n        protected abstract List<Action> search(Problem problem);\n\n        protected abstract void notifyViewOfMetrics();\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/SolutionChecker.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework\n{    \n    /**\n     * A specialization of the GoalTest interface so that it is possible to check\n     * the solution once a Goal has been identified to determine if it is\n     * acceptable. This allows you to continue searching for alternative solutions\n     * without having to restart the search.\n     * \n     * However, care needs to be taken when doing this as it does not always make\n     * sense to continue with a search once an initial goal is found, for example if\n     * using a heuristic targeted at a single goal.\n     * \n     * @author Ciaran O'Reilly\n     */\n    public interface SolutionChecker : GoalTest\n    {\n        /**\n         * This method is only called if GoalTest.isGoalState() returns true.\n         * \n         * @param actions\n         *            the list of actions to get to the goal state.\n         * \n         * @param goal\n         *            the goal the list of actions will reach.\n         * \n         * @return true if the solution is acceptable, false otherwise, which\n         *         indicates the search should be continued.\n         */\n        bool isAcceptableSolution(List<Action> actions, System.Object goal);\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/problem/ActionsFunction.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.search.framework.problem\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 67.<br>\n     * <br>\n     * Given a particular state s, ACTIONS(s) returns the set of actions that can be\n     * executed in s. We say that each of these actions is <b>applicable</b> in s.\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface ActionsFunction\n    {\n        /**\n         * Given a particular state s, returns the set of actions that can be\n         * executed in s.\n         * \n         * @param s\n         *            a particular state.\n         * @return the set of actions that can be executed in s.\n         */\n        HashSet<Action> actions(System.Object s);\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/problem/BidirectionalProblem.cs",
    "content": "using System.Collections.Generic;\n\nnamespace aima.core.search.framework.problem\n{\n    /**\n     * An interface describing a problem that can be tackled from both directions at\n     * once (i.e InitialState<->Goal).\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public interface BidirectionalProblem\n    {\n        Problem getOriginalProblem();\n\n        Problem getReverseProblem();\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/problem/DefaultGoalTest.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.search.framework.problem\n{\n    /**\n     * Checks whether a given state equals an explicitly specified goal state.\n     * \n     * @author Ruediger Lunde\n     */\n    public class DefaultGoalTest : GoalTest\n    {\n\n    private Object goalState;\n\n    public DefaultGoalTest(Object goalState)\n    {\n        this.goalState = goalState;\n    }\n\n    public bool isGoalState(Object state)\n    {\n        return goalState.Equals(state);\n    }\n}\n}"
  },
  {
    "path": "aima-csharp/search/framework/problem/DefaultStepCostFunction.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.search.framework.problem\n{\n    /**\n     * Returns one for every action.\n     * \n     * @author Ravi Mohan\n     */\n    public class DefaultStepCostFunction : StepCostFunction\n    {\n\n\n        public double c(System.Object stateFrom, Action action, System.Object stateTo)\n        {\n            return 1;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/problem/GoalTest.cs",
    "content": "using System.Collections.Generic;\n\nnamespace aima.core.search.framework.problem\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 67.<br>\n     * <br>\n     * The goal test, which determines whether a given state is a goal state.\n     * \n     * @author Ravi Mohan\n     * @author Mike Stampone\n     */\n    public interface GoalTest\n    {\n        /**\n         * Returns <code>true</code> if the given state is a goal state.\n         * \n         * @return <code>true</code> if the given state is a goal state.\n         */\n        bool isGoalState(System.Object state);\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/problem/Problem.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.search.framework.problem\n{\n    /**\n * Artificial Intelligence A Modern Approach (3rd Edition): page 66.<br>\n * <br>\n * A problem can be defined formally by five components: <br>\n * <ul>\n * <li>The <b>initial state</b> that the agent starts in.</li>\n * <li>A description of the possible <b>actions</b> available to the agent.\n * Given a particular state s, ACTIONS(s) returns the set of actions that can be\n * executed in s.</li>\n * <li>A description of what each action does; the formal name for this is the\n * <b>transition model, specified by a function RESULT(s, a) that returns the\n * state that results from doing action a in state s.</b></li>\n * <li>The <b>goal test</b>, which determines whether a given state is a goal\n * state.</li>\n * <li>A <b>path cost</b> function that assigns a numeric cost to each path. The\n * problem-solving agent chooses a cost function that reflects its own\n * performance measure. The <b>step cost</b> of taking action a in state s to\n * reach state s' is denoted by c(s,a,s')</li>\n * </ul>\n * \n * @author Ravi Mohan\n * @author Ciaran O'Reilly\n * @author Mike Stampone\n */\n\n    public class Problem\n    {\n        protected Object initialState;\n\n        protected ActionsFunction actionsFunction;\n\n        protected ResultFunction resultFunction;\n\n        protected GoalTest goalTest;\n\n        protected StepCostFunction stepCostFunction;\n\n        /**\n\t * Constructs a problem with the specified components, and a default step\n    \t * cost function (i.e. 1 per step).\n    \t * \n    \t * @param initialState\n    \t *            the initial state that the agent starts in.\n    \t * @param actionsFunction\n\t *            a description of the possible actions available to the agent.\n    \t * @param resultFunction\n    \t *            a description of what each action does; the formal name for\n    \t *            this is the transition model, specified by a function\n    \t *            RESULT(s, a) that returns the state that results from doing\n    \t *            action a in state s.\n    \t * @param goalTest\n    \t *            test determines whether a given state is a goal state.\n    \t */\n        public Problem(Object initialState, ActionsFunction actionsFunction,\n                ResultFunction resultFunction, GoalTest goalTest)\n            : this(initialState, actionsFunction, resultFunction, goalTest,\n                new DefaultStepCostFunction())\n        {\n\n        }\n\n        /**\n\t * Constructs a problem with the specified components, which includes a step\n\t * cost function.\n\t * \n\t * @param initialState\n\t *            the initial state of the agent.\n\t * @param actionsFunction\n\t *            a description of the possible actions available to the agent.\n\t * @param resultFunction\n\t *            a description of what each action does; the formal name for\n\t *            this is the transition model, specified by a function\n\t *            RESULT(s, a) that returns the state that results from doing\n\t *            action a in state s.\n\t * @param goalTest\n\t *            test determines whether a given state is a goal state.\n\t * @param stepCostFunction\n\t *            a path cost function that assigns a numeric cost to each path.\n\t *            The problem-solving-agent chooses a cost function that\n\t *            reflects its own performance measure.\n\t */\n        public Problem(Object initialState, ActionsFunction actionsFunction,\n               ResultFunction resultFunction, GoalTest goalTest,\n               StepCostFunction stepCostFunction)\n        {\n            this.initialState = initialState;\n            this.actionsFunction = actionsFunction;\n            this.resultFunction = resultFunction;\n            this.goalTest = goalTest;\n            this.stepCostFunction = stepCostFunction;\n        }\n\n        /**\n\t * Returns the initial state of the agent.\n    \t * \n    \t * @return the initial state of the agent.\n\t */\n        public Object getInitialState()\n        {\n            return initialState;\n        }\n\n        /**\n    \t * Returns <code>true</code> if the given state is a goal state.\n    \t * \n    \t * @return <code>true</code> if the given state is a goal state.\n    \t */\n        public bool isGoalState(Object state)\n        {\n            return goalTest.isGoalState(state);\n        }\n\n        /**\n\t * Returns the goal test.\n\t * \n\t * @return the goal test.\n\t */\n        public GoalTest getGoalTest()\n        {\n            return goalTest;\n        }\n\n        /**\n\t * Returns the description of the possible actions available to the agent.\n\t * \n\t * @return the description of the possible actions available to the agent.\n\t */\n        public ActionsFunction getActionsFunction()\n        {\n            return actionsFunction;\n        }\n\n        /**\n\t * Returns the description of what each action does.\n\t * \n\t * @return the description of what each action does.\n\t */\n        public ResultFunction getResultFunction()\n        {\n            return resultFunction;\n        }\n\n        /**\n         * Returns the path cost function.\n         * \n         * @return the path cost function.\n         */\n        public StepCostFunction getStepCostFunction()\n        {\n            return stepCostFunction;\n        }\n\n        // PROTECTED METHODS\n\n        protected Problem()\n        {\n\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/problem/ResultFunction.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\n\nnamespace aima.core.search.framework.problem\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 67.<br>\n     * <br>\n     * A description of what each action does; the formal name for this is the\n     * transition model, specified by a function RESULT(s, a) that returns the state\n     * that results from doing action a in state s. We also use the term successor\n     * to refer to any state reachable from a given state by a single action.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public interface ResultFunction\n    {\n        /**\n         * Returns the state that results from doing action a in state s\n         * \n         * @param s\n         *            a particular state.\n         * @param a\n         *            an action to be performed in state s.\n         * @return the state that results from doing action a in state s.\n         */\n        System.Object result(System.Object s, Action a);\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/problem/StepCostFunction.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nnamespace aima.core.search.framework.problem\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 68.<br>\n     * <br>\n     * The <b>step cost</b> of taking action a in state s to reach state s' is\n     * denoted by c(s, a, s').\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     */\n    public interface StepCostFunction\n    {\n        /**\n         * Calculate the step cost of taking action a in state s to reach state s'.\n         * \n         * @param s\n         *            the state from which action a is to be performed.\n         * @param a\n         *            the action to be taken.\n         * \n         * @param sDelta\n         *            the state reached by taking the action.\n         * @return the cost of taking action a in state s to reach state s'.\n         */\n        double c(System.Object s, Action a, System.Object sDelta);\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/qsearch/GraphSearch.cs",
    "content": "using System.Collections.Generic;\nusing System.Linq;\nusing aima.core.agent;\nusing aima.core.search.framework;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework.qsearch\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 3.7, page 77.\n     * <br>\n     * \n     * <pre>\n     * function GRAPH-SEARCH(problem) returns a solution, or failure\n     *   initialize the frontier using the initial state of problem\n     *   initialize the explored set to be empty\n     *   loop do\n     *     if the frontier is empty then return failure\n     *     choose a leaf node and remove it from the frontier\n     *     if the node contains a goal state then return the corresponding solution\n     *     add the node to the explored set\n     *     expand the chosen node, adding the resulting nodes to the frontier\n     *       only if not in the frontier or explored set\n     * </pre>\n     * \n     * Figure 3.7 An informal description of the general graph-search algorithm.\n     * <br>\n     * This implementation is based on the template method\n     * {@link #search(Problem, Queue)} from superclass {@link QueueSearch} and\n     * provides implementations for the needed primitive operations. In contrast to\n     * the code above, here, nodes resulting from node expansion are added to the\n     * frontier even if nodes with equal states already exist there. This makes it\n     * possible to use the implementation also in combination with priority queue\n     * frontiers.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * @author Ruediger Lunde\n     */\n    public class GraphSearch : QueueSearch\n    {\n\tprivate HashSet<object> explored = new HashSet<object>();\n\n\tpublic GraphSearch() : this(new NodeExpander())\n\t{\n\n\t}\n\n\tpublic GraphSearch(NodeExpander nodeExpander): base(nodeExpander)\n\t{\n\t    \n\t}\n\n\t/**\n\t * Clears the set of explored states and calls the search implementation of\n\t * <code>QueSearch</code>\n\t */\t\n\tpublic override List<Action> search(Problem problem, Queue<Node> frontier)\n\t{\n\t    // initialize the explored set to be empty\n\t    explored.Clear();\n\t    // expandedNodes = new List<Node>();\n\t    return base.search(problem, frontier);\n\t}\n\n\t/**\n\t * Inserts the node at the tail of the frontier if the corresponding state\n\t * was not yet explored.\n\t */\n\tprotected override void addToFrontier(Node node)\n\t{\n\t    if (!explored.Contains(node.State))\n\t    {\n\t\tfrontier.Enqueue(node);\n\t\tupdateMetrics(frontier.Count);\n\t    }\n\t}\n\n\t/**\n\t * Removes the node at the head of the frontier, adds the corresponding\n\t * state to the explored set, and returns the node. As the template method\n\t * (the caller) calls {@link #isFrontierEmpty() before, the resulting node\n\t * state will always be unexplored yet.\n\t * \n\t * @return the node at the head of the frontier.\n\t */\n\tprotected override Node removeFromFrontier()\n\t{\n\t    Node result = frontier.Dequeue();\n\t    // add the node to the explored set\n\t    explored.Add(result.State);\n\t    updateMetrics(frontier.Count);\n\t    return result;\n\t}\n\n\t/**\n\t * Pops nodes of already explored states from the top end of the frontier\n\t * and checks whether there are still some nodes left.\n\t */\n\tprotected override bool isFrontierEmpty()\n\t{\n\t    while (!(frontier.Count==0) && explored.Contains(frontier.Peek().State))\n\t\t{\n\t\t    frontier.Dequeue();\n\t\t}\n\t    updateMetrics(frontier.Count);\n\t    if (frontier.Count == 0)\n\t    {\n\t\treturn true;\n\t    }\n\t    else\n\t\treturn false;\n\t}\t\n    }\n}"
  },
  {
    "path": "aima-csharp/search/framework/qsearch/GraphSearchBFS.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.search.framework;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework.qsearch\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 3.7, page 77.\n     * <br>\n     * \n     * <pre>\n     * function GRAPH-SEARCH(problem) returns a solution, or failure\n     *   initialize the frontier using the initial state of problem\n     *   initialize the explored set to be empty\n     *   loop do\n     *     if the frontier is empty then return failure\n     *     choose a leaf node and remove it from the frontier\n     *     if the node contains a goal state then return the corresponding solution\n     *     add the node to the explored set\n     *     expand the chosen node, adding the resulting nodes to the frontier\n     *       only if not in the frontier or explored set\n     * </pre>\n     * \n     * Figure 3.7 An informal description of the general graph-search algorithm.\n     * <br>\n     * This implementation is based on the template method\n     * {@link #search(Problem, Queue)} from superclass {@link QueueSearch} and\n     * provides implementations for the needed primitive operations. It is the most\n     * efficient variant of graph search for breadth first search. But don't expect\n     * shortest paths in combination with priority queue frontiers.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * @author Ruediger Lunde\n     */\n    public class GraphSearchBFS : QueueSearch\n    {\n\tprivate HashSet<object> explored = new HashSet<object>();\n\tprivate HashSet<object> frontierStates = new HashSet<object>();\n\n\tpublic GraphSearchBFS() : this(new NodeExpander())\n\t{\n\n\t}\n\n\tpublic GraphSearchBFS(NodeExpander nodeExpander) : base(nodeExpander)\n\t{\n\n\t}\n\n\t/**\n\t * Clears the set of explored states and calls the search implementation of\n\t * <code>QueSearch</code>\n\t */\n\tpublic override List<Action> search(Problem problem, Queue<Node> frontier)\n\t{\n\t    // Initialize the explored set to be empty\n\t    explored.Clear();\n\t    frontierStates.Clear();\n\t    return base.search(problem, frontier);\n\t}\n\n\t/**\n\t * Inserts the node at the tail of the frontier if the corresponding state\n\t * is not already a frontier state and was not yet explored.\n\t */\n\tprotected override void addToFrontier(Node node)\n\t{\n\t    if (!explored.Contains(node.State) && !frontierStates.Contains(node.State))\n\t    {\n\t\tfrontier.Enqueue(node);\n\t\tfrontierStates.Add(node.State);\n\t\tupdateMetrics(frontier.Count);\n\t    }\n\t}\n\n\t/**\n\t * Removes the node at the head of the frontier, adds the corresponding\n\t * state to the explored set, and returns the node.\n\t * \n\t * @return the node at the head of the frontier.\n\t */\n\tprotected override Node removeFromFrontier()\n\t{\n\t    Node result = frontier.Dequeue();\n\t    explored.Add(result.State);\n\t    frontierStates.Remove(result.State);\n\t    updateMetrics(frontier.Count);\n\t    return result;\n\t}\n\n\t/**\n\t * Checks whether there are still some nodes left.\n\t */\n\tprotected override bool isFrontierEmpty()\n\t{\n\t    if (frontier.Count == 0)\n\t    {\n\t\treturn true;\n\t    }\n\t    else\n\t\treturn false;\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/search/framework/qsearch/QueueSearch.cs",
    "content": "using System.Collections.Generic;\nusing System.Threading;\nusing aima.core.agent;\nusing aima.core.util;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework.qsearch\n{\n    /**\n     * Base class for queue-based search implementations, especially for {@link TreeSearch},\n     * {@link GraphSearch}, and {@link BidirectionalSearch}.\n     * \n     * @author Ravi Mohan\n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     * @author Ruediger Lunde\n     */\n     public abstract class QueueSearch\n    {\n        public const System.String METRIC_NODES_EXPANDED = \"nodesExpanded\";\n        public const System.String METRIC_QUEUE_SIZE = \"queueSize\";\n\tpublic const System.String METRIC_MAX_QUEUE_SIZE = \"maxQueueSize\";\n\tpublic const System.String METRIC_PATH_COST = \"pathCost\";\n\n        protected readonly NodeExpander nodeExpander;\n        protected Queue<Node> frontier;\n        protected bool earlyGoalCheck = false;\n        protected Metrics metrics = new Metrics();\n\n        protected QueueSearch(NodeExpander nodeExpander)\n        {\n            this.nodeExpander = nodeExpander;\n        }\n\n        public virtual NodeExpander getNodeExpander()\n        {\n            return nodeExpander;\n        }\n\n        /**\n\t * Returns a list of actions to the goal if the goal was found, a list\n\t * containing a single NoOp Action if already at the goal, or an empty list\n    \t * if the goal could not be found. This template method provides a base for\n    \t * tree and graph search implementations. It can be customized by overriding\n    \t * some primitive operations, especially {@link #addToFrontier(Node)},\n    \t * {@link #removeFromFrontier()}, and {@link #isFrontierEmpty()}.\n    \t * \n    \t * @param problem\n    \t *            the search problem\n    \t * @param frontier\n    \t *            the collection of nodes that are waiting to be expanded\n    \t * \n    \t * @return a list of actions to the goal if the goal was found, a list\n    \t *         containing a single NoOp Action if already at the goal, or an\n    \t *         empty list if the goal could not be found.\n    \t */\n         public virtual List<Action> search(Problem problem, Queue<Node> frontier)\n        {\n            this.frontier = frontier;\n            clearInstrumentation();\n            // initialize the frontier using the initial state of the problem\n            Node root = nodeExpander.createRootNode(problem.getInitialState());\n            if (earlyGoalCheck)\n            {\n                if(SearchUtils.isGoalState(problem, root))\n                {\n                    return getSolution(root);\n                }\n            }\n            addToFrontier(root);\n            while(!(frontier.Count == 0))\n            {\n                // choose a leaf node and remove it from the frontier\n                Node nodeToExpand = removeFromFrontier();\n                // Only need to check the nodeToExpand if have not already\n                // checked before adding to the frontier\n                if (!earlyGoalCheck)\n                {\n                    // if the node contains a goal state then return the\n                    // corresponding solution\n                    if(SearchUtils.isGoalState(problem, nodeToExpand))\n                    {\n                        return getSolution(nodeToExpand);\n                    }\n                }\n                // expand the chosen node, adding the resulting nodes to the\n                // frontier\n                foreach(Node successor in nodeExpander.expand(nodeToExpand, problem))\n                {\n                    if (earlyGoalCheck)\n                    {\n                        if(SearchUtils.isGoalState(problem, successor))\n                        {\n                            return getSolution(successor);\n                        }\n                    }\n                    addToFrontier(successor)\n;                }\n            }\n            // if the frontier is empty then return failure\n            return SearchUtils.failure();\n        }\n        /**\n\t * Primitive operation which inserts the node at the tail of the frontier.\n\t */\n        protected abstract void addToFrontier(Node node);\n\n        /**\n\t * Primitive operation which removes and returns the node at the head of the\n\t * frontier.\n\t * \n\t * @return the node at the head of the frontier.\n\t */\n        protected abstract Node removeFromFrontier();\n\n        /**\n\t * Primitive operation which checks whether the frontier contains not yet\n\t * expanded nodes.\n\t */\n        protected abstract bool isFrontierEmpty();\n\n        /**\n\t * Enables optimization for FIFO queue based search, especially breadth\n\t * first search.\n\t * \n\t * @param state\n\t */\n        public void setEarlyGoalCheck(bool state)\n        {\n            this.earlyGoalCheck = state;\n        }\n\n        /**\n\t * Returns all the search metrics.\n\t */\n        public virtual Metrics getMetrics()\n        {\n            metrics.set(METRIC_NODES_EXPANDED, nodeExpander.getNumOfExpandCalls());\n            return metrics;\n        }\n\n        /**\n\t * Sets all metrics to zero.\n\t */\n        public void clearInstrumentation()\n        {\n            nodeExpander.resetCounter();\n            metrics.set(METRIC_NODES_EXPANDED, 0);\n            metrics.set(METRIC_QUEUE_SIZE, 0);\n            metrics.set(METRIC_MAX_QUEUE_SIZE, 0);\n            metrics.set(METRIC_PATH_COST, 0);\n        }\n\n        protected void updateMetrics(int queueSize)\n        {\n            metrics.set(METRIC_QUEUE_SIZE, queueSize);\n            int maxQSize = metrics.getInt(METRIC_MAX_QUEUE_SIZE);\n            if (queueSize > maxQSize)\n            {\n                metrics.set(METRIC_MAX_QUEUE_SIZE, queueSize);\n            }\n        }\n\n        private List<Action> getSolution(Node node)\n        {\n            metrics.set(METRIC_PATH_COST, node.PathCost);\n            return SearchUtils.getSequenceOfActions(node);\n        }\n    }\n}\n"
  },
  {
    "path": "aima-csharp/search/framework/qsearch/TreeSearch.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.search.framework;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.framework.qsearch\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 3.7, page 77.\n     * <br>\n     * \n     * <pre>\n     * function TREE-SEARCH(problem) returns a solution, or failure\n     *   initialize the frontier using the initial state of the problem\n     *   loop do\n     *     if the frontier is empty then return failure\n     *     choose a leaf node and remove it from the frontier\n     *     if the node contains a goal state then return the corresponding solution\n     *     expand the chosen node, adding the resulting nodes to the frontier\n     * </pre>\n     * \n     * Figure 3.7 An informal description of the general tree-search algorithm.\n     * \n     * <br>\n     * This implementation is based on the template method\n     * {@link #search(Problem, Queue)} from superclass {@link QueueSearch} and\n     * provides implementations for the needed primitive operations.\n     * \n     * @author Ravi Mohan\n     * @author Ruediger Lunde\n     * \n     */\n     public class TreeSearch : QueueSearch\n    {\n\tpublic TreeSearch(): this(new NodeExpander())\n\t{\n\n\t}\n\n\tpublic TreeSearch(NodeExpander nodeExpander): base(nodeExpander)\n\t{\n\t    \n\t}\n\n\t/**\n\t * Inserts the node at the tail of the frontier.\n\t */\t\n\tprotected override void addToFrontier(Node node)\n\t{\n\t    frontier.Enqueue(node);\n\t    updateMetrics(frontier.Count);\n\t}\n\n\t/**\n\t * Removes and returns the node at the head of the frontier.\n\t * \n\t * @return the node at the head of the frontier.\n\t */\n\tprotected override Node removeFromFrontier()\n\t{\n\t    Node result = frontier.Dequeue();\n\t    updateMetrics(frontier.Count);\n\t    return result;\n\t}\n\n\t/**\n\t * Checks whether the frontier contains not yet expanded nodes.\n\t */\n\tprotected override bool isFrontierEmpty()\n\t{\n\t    if(frontier.Count == 0)\n\t    {\n\t\treturn true;\n\t    }\n\t    else\n\t\treturn false;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/search/online/LRTAStarAgent.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.search.framework;\nusing aima.core.util;\n\nnamespace aima.core.search.online\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 4.24, page\n     * 152.<br>\n     * <br>\n     * \n     * <pre>\n     * function LRTA*-AGENT(s') returns an action\n     *   inputs: s', a percept that identifies the current state\n     *   persistent: result, a table, indexed by state and action, initially empty\n     *               H, a table of cost estimates indexed by state, initially empty\n     *               s, a, the previous state and action, initially null\n     *           \n     *   if GOAL-TEST(s') then return stop\n     *   if s' is a new state (not in H) then H[s'] &lt;- h(s')\n     *   if s is not null\n     *     result[s, a] &lt;- s'\n     *     H[s] &lt;-        min LRTA*-COST(s, b, result[s, b], H)\n     *             b (element of) ACTIONS(s)\n     *   a &lt;- an action b in ACTIONS(s') that minimizes LRTA*-COST(s', b, result[s', b], H)\n     *   s &lt;- s'\n     *   return a\n     *   \n     * function LRTA*-COST(s, a, s', H) returns a cost estimate\n     *   if s' is undefined then return h(s)\n     *   else return c(s, a, s') + H[s']\n     * </pre>\n     * \n     * Figure 4.24 LRTA*-AGENT selects an action according to the value of\n     * neighboring states, which are updated as the agent moves about the state\n     * space.<br>\n     * <br>\n     * <b>Note:</b> This algorithm fails to exit if the goal does not exist (e.g.\n     * A<->B Goal=X), this could be an issue with the implementation. Comments\n     * welcome.\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n    public class LRTAStarAgent : AbstractAgent\n    {\n\tprivate OnlineSearchProblem problem;\n\tprivate PerceptToStateFunction ptsFunction;\n\tprivate HeuristicFunction hf;\n\t// persistent: result, a table, indexed by state and action, initially empty\n\tprivate readonly TwoKeyHashMap<object, Action, object> result = new TwoKeyHashMap<object, Action, object>();\n\t// H, a table of cost estimates indexed by state, initially empty\n\tprivate readonly Dictionary<object, double> H = new Dictionary<object, double>();\n\t// s, a, the previous state and action, initially null\n\tprivate object s = null;\n\tprivate Action a = null;\n\n\t/**\n\t * Constructs a LRTA* agent with the specified search problem, percept to\n\t * state function, and heuristic function.\n\t * \n\t * @param problem\n\t *            an online search problem for this agent to solve.\n\t * @param ptsFunction\n\t *            a function which returns the problem state associated with a\n\t *            given Percept.\n\t * @param hf\n\t *            heuristic function <em>h(n)</em>, which estimates the cost of\n\t *            the cheapest path from the state at node <em>n</em> to a goal\n\t *            state.\n\t */\n\tpublic LRTAStarAgent(OnlineSearchProblem problem,\n\t\t\tPerceptToStateFunction ptsFunction, HeuristicFunction hf)\n\t{\n\t    setProblem(problem);\n\t    setPerceptToStateFunction(ptsFunction);\n\t    setHeuristicFunction(hf);\n\t}\n\n\t/**\n\t * Returns the search problem of this agent.\n\t * \n\t * @return the search problem of this agent.\n\t */\n\tpublic OnlineSearchProblem getProblem()\n\t{\n\t    return problem;\n\t}\n\n\t/**\n\t * Sets the search problem for this agent to solve.\n\t * \n\t * @param problem\n\t *            the search problem for this agent to solve.\n\t */\n\tpublic void setProblem(OnlineSearchProblem problem)\n\t{\n\t    this.problem = problem;\n\t    init();\n\t}\n\n\t/**\n\t * Returns the percept to state function of this agent.\n\t * \n\t * @return the percept to state function of this agent.\n\t */\n\tpublic PerceptToStateFunction getPerceptToStateFunction()\n\t{\n\t    return ptsFunction;\n\t}\n\n\t/**\n\t * Sets the percept to state function of this agent.\n\t * \n\t * @param ptsFunction\n\t *            a function which returns the problem state associated with a\n\t *            given Percept.\n\t */\n\tpublic void setPerceptToStateFunction(PerceptToStateFunction ptsFunction)\n\t{\n\t    this.ptsFunction = ptsFunction;\n\t}\n\n\t/**\n\t * Returns the heuristic function of this agent.\n\t */\n\tpublic HeuristicFunction getHeuristicFunction()\n\t{\n\t    return hf;\n\t}\n\n\t/**\n\t * Sets the heuristic function of this agent.\n\t * \n\t * @param hf\n\t *            heuristic function <em>h(n)</em>, which estimates the cost of\n\t *            the cheapest path from the state at node <em>n</em> to a goal\n\t *            state.\n\t */\n\tpublic void setHeuristicFunction(HeuristicFunction hf)\n\t{\n\t    this.hf = hf;\n\t}\n\n\t// function LRTA*-AGENT(s') returns an action\n\t// inputs: s', a percept that identifies the current state\n\tpublic override Action execute(Percept psDelta)\n\t{\n\t    object sDelta = ptsFunction.getState(psDelta);\n\t    // if GOAL-TEST(s') then return stop\n\t    if(goalTest(sDelta))\n\t    {\n\t\ta = NoOpAction.NO_OP;\n\t    }\n\t    else\n\t    {\n\t\t// if s' is a new state (not in H) then H[s'] <- h(s')\n\t\tif(!H.ContainsKey(sDelta))\n\t\t{\n\t\t    H.Add(sDelta, getHeuristicFunction().h(sDelta));\n\t\t}\n\t\t// if s is not null\n\t\tif(null != s)\n\t\t{\n\t\t    // result[s, a] <- s'\n\t\t    result.put(s, a, sDelta);\n\n\t\t    // H[s] <- min LRTA*-COST(s, b, result[s, b], H)\n\t\t    // b (element of) ACTIONS(s)\n\t\t    double minimum = double.MaxValue;\n\t\t    foreach(Action b in actions(s))\n\t\t    {\n\t\t\tdouble cost = lrtaCost(s, b, result.get(s, b));\n\t\t\tif(cost < minimum)\n\t\t\t{\n\t\t\t    minimum = cost;\n\t\t\t}\n\t\t    }\n\t\t    H.Add(s, minimum);\n\t\t}\n\t\t// a <- an action b in ACTIONS(s') that minimizes LRTA*-COST(s', b,\n\t\t// result[s', b], H)\n\t\tdouble min = double.MaxValue;\n\t\t// Just in case no actions\n\t\ta = NoOpAction.NO_OP;\n\t\tforeach(agent.Action b in actions(sDelta))\n\t\t{\n\t\t    double cost = lrtaCost(sDelta, b, result.get(sDelta, b));\n\t\t    if(cost < min)\n\t\t    {\n\t\t\tmin = cost;\n\t\t\ta = b;\n\t\t    }\n\t\t}\n\t    }\n\n\t    // s <- s'\n\t    s = sDelta;\n\n\t    if (a.isNoOp())\n\t    {\n\t\t// I'm either at the Goal or can't get to it,\n\t\t// which in either case I'm finished so just die.\n\t\tsetAlive(false);\n\t    }\n\t    // return a\n\t    return a;\n\t}\n\n\t// PRIVATE METHODS\n\t\n\tprivate void init()\n\t{\n\t    setAlive(true);\n\t    result.Clear();\n\t    H.Clear();\n\t    s = null;\n\t    a = null;\n\t}\n\n\tprivate bool goalTest(object state)\n\t{\n\t    return getProblem().isGoalState(state);\n\t}\n\n\t// function LRTA*-COST(s, a, s', H) returns a cost estimate\n\tprivate double lrtaCost(object s, Action action, object sDelta)\n\t{\n\t    // if s' is undefined then return h(s)\n\t    if (null == sDelta)\n\t    {\n\t\treturn getHeuristicFunction().h(s);\n\t    }\n\t    // else return c(s, a, s') + H[s']\n\t    return getProblem().getStepCostFunction().c(s, action, sDelta)\n\t\t\t    + H[sDelta];\n\t}\n\n\tprivate HashSet<Action> actions(object state)\n\t{\n\t    return problem.getActionsFunction().actions(state);\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/search/online/OnlineDFSAgent.cs",
    "content": "using System.Collections.Generic;\nusing aima.core.agent;\nusing aima.core.agent.impl;\nusing aima.core.search.framework;\nusing aima.core.util;\n\nnamespace aima.core.search.online\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): Figure 4.21, page\n     * 150.<br>\n     * <br>\n     * \n     * <pre>\n     * function ONLINE-DFS-AGENT(s') returns an action\n     *   inputs: s', a percept that identifies the current state\n     *   persistent: result, a table, indexed by state and action, initially empty\n     *               untried, a table that lists, for each state, the actions not yet tried\n     *               unbacktracked, a table that lists, for each state, the backtracks not yet tried\n     *               s, a, the previous state and action, initially null\n     *    \n     *   if GOAL-TEST(s') then return stop\n     *   if s' is a new state (not in untried) then untried[s'] &lt;- ACTIONS(s')\n     *   if s is not null then\n     *       result[s, a] &lt;- s'\n     *       add s to the front of the unbacktracked[s']\n     *   if untried[s'] is empty then\n     *       if unbacktracked[s'] is empty then return stop\n     *       else a &lt;- an action b such that result[s', b] = POP(unbacktracked[s'])\n     *   else a &lt;- POP(untried[s'])\n     *   s &lt;- s'\n     *   return a\n     * </pre>\n     * \n     * Figure 4.21 An online search agent that uses depth-first exploration. The\n     * agent is applicable only in state spaces in which every action can be\n     * \"undone\" by some other action.<br>\n     * \n     * @author Ciaran O'Reilly\n     * \n     */\n    public class OnlineDFSAgent : AbstractAgent\n    {\n\tprivate OnlineSearchProblem problem;\n\tprivate PerceptToStateFunction ptsFunction;\n\tprivate readonly TwoKeyHashMap<object, Action, object> result = new TwoKeyHashMap<object, Action, object>();\n\t// untried, a table that lists, for each state, the actions not yet tried\n\tprivate readonly Dictionary<object, List<agent.Action>> untried = new Dictionary<object, List<Action>>();\n\t// unbacktracked, a table that lists,\n\t// for each state, the backtracks not yet tried\n\tprivate readonly Dictionary<object, List<object>> unbacktracked = new Dictionary<object, List<object>>();\n\t// s, a, the previous state and action, initially null\n\tprivate object s = null;\n\tprivate Action a = null;\n\n\t/**\n\t * Constructs an online DFS agent with the specified search problem and\n\t * percept to state function.\n\t * \n\t * @param problem\n\t *            an online search problem for this agent to solve\n\t * @param ptsFunction\n\t *            a function which returns the problem state associated with a\n\t *            given Percept.\n\t */\n\tpublic OnlineDFSAgent(OnlineSearchProblem problem,\n\t\t\tPerceptToStateFunction ptsFunction)\n\t{\n\t    setProblem(problem);\n\t    setPerceptToStateFunction(ptsFunction);\n\t}\n\n\t/**\n\t * Returns the search problem for this agent.\n\t * \n\t * @return the search problem for this agent.\n\t */\n\tpublic OnlineSearchProblem getProblem()\n\t{\n\t    return problem;\n\t}\n\n\t/**\n\t * Sets the search problem for this agent to solve.\n\t * \n\t * @param problem\n\t *            the search problem for this agent to solve.\n\t */\n\tpublic void setProblem(OnlineSearchProblem problem)\n\t{\n\t    this.problem = problem;\n\t    init();\n\t}\n\n\t/**\n\t * Returns the percept to state function of this agent.\n\t * \n\t * @return the percept to state function of this agent.\n\t */\n\tpublic PerceptToStateFunction getPerceptToStateFunction()\n\t{\n\t    return ptsFunction;\n\t}\n\n\t/**\n\t * Sets the percept to state functino of this agent.\n\t * \n\t * @param ptsFunction\n\t *            a function which returns the problem state associated with a\n\t *            given Percept.\n\t */\n\tpublic void setPerceptToStateFunction(PerceptToStateFunction ptsFunction)\n\t{\n\t    this.ptsFunction = ptsFunction;\n\t}\n\n\t// function ONLINE-DFS-AGENT(s') returns an action\n\t// inputs: s', a percept that identifies the current state\n\tpublic override Action execute(Percept psDelta)\n\t{\n\t    object sDelta = ptsFunction.getState(psDelta);\n\t    // if GOAL-TEST(s') then return stop\n\t    if (goalTest(sDelta))\n\t    {\n\t\ta = NoOpAction.NO_OP;\n\t    }\n\t    else\n\t    {\n\t\t// if s' is a new state (not in untried) then untried[s'] <-\n\t\t// ACTIONS(s')\n\t\tif (!untried.ContainsKey(sDelta))\n\t\t{\n\t\t    untried.Add(sDelta, actions(sDelta));\n\t\t}\n\n\t\t// if s is not null then do\n\t\tif (null != s)\n\t\t{\n\t\t    // Note: If I've already seen the result of this\n\t\t    // [s, a] then don't put it back on the unbacktracked\n\t\t    // list otherwise you can keep oscillating\n\t\t    // between the same states endlessly.\n\t\t    if (!(sDelta.Equals(result.get(s, a))))\n\t\t    {\n\t\t\t// result[s, a] <- s'\n\t\t\tresult.put(s, a, sDelta);\n\n\t\t\t// Ensure the unbacktracked always has a list for s'\n\t\t\tif (!unbacktracked.ContainsKey(sDelta))\n\t\t\t{\n\t\t\t    unbacktracked.Add(sDelta, new List<object>());\n\t\t\t}\n\n\t\t\t// add s to the front of the unbacktracked[s']\n\t\t\tunbacktracked[sDelta].Add(s);\n\t\t    }\n\t\t}\n\n\t\t// if untried[s'] is empty then\n\t\tif (untried[sDelta].Capacity == 0)\n\t\t{\n\t\t    // if unbacktracked[s'] is empty then return stop\n\t\t    if (unbacktracked[sDelta].Capacity == 0)\n\t\t    {\n\t\t\ta = NoOpAction.NO_OP;\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\t// else a <- an action b such that result[s', b] =\n\t\t\t// POP(unbacktracked[s'])\n\t\t\tobject popped = unbacktracked[sDelta].Remove(0);\n\t\t\tforeach(Pair<object, Action> sa in result.Keys)\n\t\t\t{\n\t\t\t    if (sa.getFirst().Equals(sDelta) && result[sa].Equals(popped))\n\t\t\t    {\n\t\t\t\ta = sa.getSecond();\n\t\t\t\tbreak;\n\t\t\t    }\n\t\t\t}\n\t\t    }\n\t\t}\n\t\telse //Needs debugging.\n\t\t{\n\t\t    // else a <- POP(untried[s'])\n\t\t    //a = untried[sDelta].Remove(0);\n\t\t}\n\t    }\n\n\t    if (a.isNoOp())\n\t    {\n\t\t// I'm either at the Goal or can't get to it,\n\t\t// which in either case I'm finished so just die.\n\t\tsetAlive(false);\n\t    }\n\n\t    // s <- s'\n\t    s = sDelta;\n\t    // return a\n\t    return a;\n\t}\n\n\t// PRIVATE METHODS\n\n\tprivate void init()\n\t{\n\t    setAlive(true);\n\t    result.Clear();\n\t    untried.Clear();\n\t    unbacktracked.Clear();\n\t    s = null;\n\t    a = null;\n\t}\n\n\tprivate bool goalTest(object state)\n\t{\n\t    return getProblem().isGoalState(state);\n\t}\n\n\tprivate List<Action> actions(object state)\n\t{\n\t    return new List<Action>(problem.getActionsFunction()\n\t\t\t    .actions(state));\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/search/online/OnlineSearchProblem.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing aima.core.search.framework;\nusing aima.core.search.framework.problem;\n\nnamespace aima.core.search.online\n{\n    /**\n     * Artificial Intelligence A Modern Approach (3rd Edition): page 147.<br>\n     * <br>\n     * An online search problem must be solved by an agent executing actions, rather\n     * than by pure computation. We assume a deterministic and fully observable\n     * environment (Chapter 17 relaxes these assumptions), but we stipulate that the\n     * agent knows only the following: <br>\n     * <ul>\n     * <li>ACTIONS(s), which returns a list of actions allowed in state s;</li>\n     * <li>The step-cost function c(s, a, s') - note that this cannot be used until\n     * the agent knows that s' is the outcome; and</li>\n     * <li>GOAL-TEST(s).</li>\n     * </ul>\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n    public class OnlineSearchProblem\n    {\n        protected ActionsFunction actionsFunction;\n\n        protected StepCostFunction stepCostFunction;\n\n        protected GoalTest goalTest;\n\n\t/**\n         * Constructs an online search problem with the specified action function,\n         * goal test, and a default step cost function.\n         * \n         * @param actionsFunction\n         *            ACTIONS(s), which returns a list of actions allowed in state s\n         * @param goalTest\n         *            GOAL-TEST(s), which the agent can apply to a single state\n         *            description to determine if it is a goal state\n         */\n\tpublic OnlineSearchProblem(ActionsFunction actionsFunction,\n                 GoalTest goalTest)\n\t{\n\t    this.actionsFunction = actionsFunction;\n\t    this.goalTest = goalTest;\n\t    this.stepCostFunction = new DefaultStepCostFunction();\n\t}\n\n\t/**\n\t * Constructs an online search problem with the specified action function,\n\t * goal test, and a default step cost function.\n\t * \n\t * @param actionsFunction\n\t *            ACTIONS(s), which returns a list of actions allowed in state s\n\t * @param goalTest\n\t *            GOAL-TEST(s), which the agent can apply to a single state\n\t *            description to determine if it is a goal state\n\t * @param stepCostFunction\n\t *            the step-cost function c(s, a, s') - note that this cannot be\n\t *            used until the agent knows that s' is the outcome\n\t */\n\tpublic OnlineSearchProblem(ActionsFunction actionsFunction,\n\t\tGoalTest goalTest, StepCostFunction stepCostFunction)\n\t{\n\t    this.actionsFunction = actionsFunction;\n\t    this.goalTest = goalTest;\n\t    this.stepCostFunction = stepCostFunction;\n\t}\n\n\t/**\n\t * Returns the action function of this online search problem.\n\t * \n\t * @return the action function of this online search problem.\n\t */\n\tpublic ActionsFunction getActionsFunction()\n\t{\n\t    return actionsFunction;\n\t}\n\n\t/**\n\t * Returns <code>true</code> if the given state is a goal state.\n\t * \n\t * @param state\n\t *            an object representing a state\n\t * \n\t * @return <code>true</code> if the given state is a goal state.\n\t */\n\tpublic bool isGoalState(Object state)\n\t{\n            return goalTest.isGoalState(state);\n\t}\n\n\t/**\n\t * Returns the step cost function of this online search problem.\n\t * \n\t * @return the step cost function of this online search problem.\n\t */\n\tpublic StepCostFunction getStepCostFunction()\n\t{\n\t    return stepCostFunction;\n\t}\n\t\t\t\t\n\t// PROTECTED METHODS\n\t\t\n\tprotected OnlineSearchProblem()\n\t{\n\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/util/ArrayIterator.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * Iterates efficiently through an array.\n     * \n     * @author Ruediger Lunde\n     */\n    public class ArrayIterator<T> : IEnumerator<T>\n    {\n        T[] values;\n        int counter;\n\n        public T Current\n        {\n            get\n            {\n                return values[counter];\n            }\n        }\n\n        object IEnumerator.Current\n        {\n            get\n            {\n                return Current;\n            }\n        }\n\n        public ArrayIterator(T[] values)\n        {\n            this.values = values;\n            counter = 0;\n        }\n\n        public bool hasNext()\n        {\n            return counter < values.Length;\n        }\n\n        public T next()\n        {\n            return values[counter++];\n        }\n\n        public void remove()\n        {\n            throw new NotSupportedException();\n        }\n               \n        public bool MoveNext()\n        {\n            counter++;\n            return (counter < values.Length);\n        }\n\n        public void Dispose()\n        {\n            throw new NotImplementedException();\n        }\n\n        public void Reset()\n        {\n            throw new NotImplementedException();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/util/CSharpRandomizer.cs",
    "content": "using System.Collections.Generic;\nusing System;\n\nnamespace aima.core.util\n{\n    /**\n     * Implementation of the Randomizer Interface using Java's java.util.Random\n     * class.\n     * \n     * @author Ravi Mohan\n     * \n     */\n    public class CSharpRandomizer : Randomizer\n    {\n\tprivate static Random _r = new Random();\n\tprivate Random r = null;\n\n\tpublic CSharpRandomizer(): this(_r)\n\t{\n\n\t}\n\n\tpublic CSharpRandomizer(Random r)\n\t{\n\t    this.r = r;\n\t}\n\n\t// START-Randomizer\n\tpublic double nextDouble()\n\t{\n\t    return r.NextDouble();\n\t}\n\n\t// END-Randomizer\n    }\n}"
  },
  {
    "path": "aima-csharp/util/DisjointSets.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace aima.core.util\n{\n    /**\n     * A basic implementation of a disjoint-set data structure for maintaining a\n     * collection of disjoint dynamic sets. This is based on the algorithm\n     * description in Chapter 21 of 'Introduction to Algorithm 2nd Edition' (by\n     * Cormen, Leriserson, Rivest, and Stein) for Disjoint-sets taking into account\n     * some of the heuristic ideas described. However, this implementation relies on\n     * the constant time performance of the HashMap's get and put operations, and\n     * HashSet's add, remove, contains and size operations as an alternative\n     * implementation approach. This provides a cleaner separation between the\n     * elements and the implementation (i.e. the idea of a representative for a\n     * particular disjoint set is not used) and an easier to use API (i.e. direct\n     * access to the disjoint set that an element belongs to and no need to\n     * understand how the internals work with respect to a representative) but will\n     * not perform as fast (proper analysis required but likely O(m + n lg n) as\n     * detailed in Theorem 21.1 on page 504 of 'Introduction to Algorithm 2nd\n     * Edition').\n     * \n     * Note: the internal implementation of this class can likely be improved to use\n     * all the techniques outlined in section 21.3 in order to get optimal\n     * performance.\n     * \n     * @author Ciaran O'Reilly\n     * \n     * @param <E>\n     *            the type of elements to be contained by the disjoint sets.\n     */\n    public class DisjointSets<E>\n    {\n\tprivate Dictionary<E, HashSet<E>> elementToSet = new Dictionary<E, HashSet<E>>();\n\tprivate LinkedHashSet<HashSet<E>> disjointSets = new LinkedHashSet<HashSet<E>>();\n\n\t/**\n\t * Default Constructor.\n\t */\n\tpublic DisjointSets()\n\t{\n\n\t}\n\n\t/**\n\t * Constructor.\n\t * \n\t * @param initialElements\n\t *            a collection of elements, each of which will be assigned to\n\t *            their own disjoint set via makeSet().\n\t */\n\tpublic DisjointSets(ICollection<E> initialElements)\n\t{\n\t    foreach (E element in initialElements)\n\t    {\n\t\tmakeSet(element);\n\t    }\n\t}\n\n\t/**\n\t * Constructor.\n\t * \n\t * @param initialElements\n\t *            a collection of elements, each of which will be assigned to\n\t *            their own disjoint set via makeSet().\n\t */\n\tpublic DisjointSets(params E[] elements)\n\t{\n\t    foreach (E element in elements)\n\t    {\n\t\tmakeSet(element);\n\t    }\n\t}\n\n\t/**\n\t * Create a disjoint set for the element passed in. This method should be\n\t * called for all elements before any of the other API methods are called\n\t * (i.e. construct a disjoint set for each element first and then union them\n\t * together as appropriate).\n\t * \n\t * @param element\n\t *            the element for which a new disjoint set should be\n\t *            constructed.\n\t */\n\tpublic void makeSet(E element)\n\t{\n\t    if (!elementToSet.ContainsKey(element))\n\t    {\n\t\t// Note: It is necessary to use an identity based hash set\n\t\t// whose equal and hashCode method are based on the Sets\n\t\t// identity and not its elements as we are adding\n\t\t// this set to a set but changing its values as unions\n\t\t// occur.\n\t\tIdentityHashSet<E> set = new IdentityHashSet<E>();\n\t\tset.Add(element);\n\t\telementToSet.Add(element, set);\n\t\tdisjointSets.Add(set);\n\t    }\n\t}\n\n\t/**\n\t * Union two disjoint sets together if the arguments currently belong to two\n\t * different sets.\n\t * \n\t * @param element1\n\t * @param element2\n\t * @throws IllegalArgumentException\n\t *             if element1 or element 2 is not already associated with a\n\t *             disjoint set (i.e. makeSet() was not called for the argument\n\t *             beforehand).\n\t */\n\tpublic void union(E element1, E element2)\n\t{\n\t    HashSet<E> set1 = elementToSet[element1];\n\t    if (set1 == null)\n\t    {\n\t\tthrow new ArgumentException(\n\t\t\t\t\"element 1 is not associated with a disjoint set, call makeSet() first.\");\n\t    }\n\t    HashSet<E> set2 = elementToSet[element2];\n\t    if (set2 == null)\n\t    {\n\t\tthrow new ArgumentException(\n\t\t\t\t\"element 2 is not associated with a disjoint set, call makeSet() first.\");\n\t    }\n\t    if (set1 != set2)\n\t    {\n\t\t// simple weighted union heuristic\n\t\tif (set1.Count < set2.Count)\n\t\t{\n\t\t    set2.Union(set1);\n\t\t    foreach (E element in set1)\n\t\t    {\n\t\t\telementToSet.Add(element, set2);\n\t\t\tdisjointSets.Remove(set2);\n\t\t    }\n\t\t}\n\t\telse\n\t\t{\n\t\t    // i.e. set1 >= set2\n\t\t    set1.Union(set2);\n\t\t    foreach (E element in set2)\n\t\t    {\n\t\t\telementToSet.Add(element, set1);\n\t\t\tdisjointSets.Remove(set1);\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\t/**\n\t * Find the disjoint set that an element belongs to.\n\t * \n\t * @param element\n\t *            the element whose disjoint set is being sought.\n\t * @return the disjoint set for the element or null if makeSet(element) was\n\t *         not previously called.\n\t */\n\tpublic LinkedHashSet<E> find(E element)\n\t{\n\t    // Note: Instantiate normal sets to ensure IdentityHashSet\n\t    // is not exposed outside of this class.\n\t    // This also ensures the internal logic cannot\n\t    // be corrupted externally due to changing sets.\n\t    return new LinkedHashSet<E>(elementToSet[element]);\n\t}\n\n\t/**\n\t * \n\t * @return a map for each element and the corresponding disjoint set that it\n\t *         belongs to.\n\t */\n\tpublic Dictionary<E, HashSet<E>> getElementToDisjointSet()\n\t{\n\t    // Note: Instantiate normal sets to ensure IdentityHashSet\n\t    // is not exposed outside of this class.\n\t    // This also ensures the internal logic cannot\n\t    // be corrupted externally due to changing sets.\n\t    Dictionary<E, HashSet<E>> result = new Dictionary<E, HashSet<E>>();\n\t    foreach (KeyValuePair<E, HashSet<E>> entry in elementToSet)\n\t    {\n\t\tresult.Add(entry.Key, new HashSet<E>(entry.Value));\n\t    }\n\t    return result;\n\t}\n\n\t/**\n\t * \n\t * @return the set of disjoint sets being maintained.\n\t */\n\tpublic HashSet<HashSet<E>> getDisjointSets()\n\t{\n\t    // Note: Instantiate normal sets to ensure IdentityHashSet\n\t    // is not exposed outside of this class.\n\t    // This also ensures the internal logic cannot\n\t    // be corrupted externally due to changing sets.\n\t    HashSet<HashSet<E>> result = new HashSet<HashSet<E>>();\n\t    IEnumerator<HashSet<E>> it = disjointSets.GetEnumerator();\n\t    while (it.MoveNext())\n\t    {\n\t\tresult.Add(new HashSet<E>(it.Current));\n\t    }\n\t    return result;\n\t}\n\n\t/**\n\t * \n\t * @return the number of disjoint sets.\n\t */\n\tpublic int numberDisjointSets()\n\t{\n\t    return disjointSets.Count;\n\t}\n\n\t/**\n\t * Remove all the disjoint sets.\n\t */\n\tpublic void clear()\n\t{\n\t    elementToSet.Clear();\n\t    disjointSets.Clear();\n\t}\n\n\t// PRIVATE METHODS\n\t\n\t// Override hashCode and equals so that\n\t// the Set itself and not its elements\n\t// are used to determine its hashCode\n\t// and equality.\n\tprivate class IdentityHashSet<H> : HashSet<H> {\n\t\tprivate static readonly long serialVersionUID = 1L;\n\t    \t\n\tpublic  int hashCode()\n\t{\n\t    return System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(this);\n\t}\n\n\tpublic bool equals(Object o)\n\t{\n\t    return this == o;\n\t}\n    }\n}\n}"
  },
  {
    "path": "aima-csharp/util/FrequencyCounter.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * A utility class for keeping counts of objects. Will return 0 for any object\n     * for which it has not recorded a count against.\n     * \n     * @author Ravi Mohan\n     * @author Mike Stampone\n     */\n    public class FrequencyCounter<T>\n    {\n        private Dictionary<T, int> counter;\n        private int total;\n\n        /**\n\t     * Default Constructor.\n\t     */\n        public FrequencyCounter()\n        {\n            counter = new Dictionary<T, int>();\n            total = 0;\n        }\n\n        /**\n\t * Returns the count to which the specified key is mapped in this frequency\n\t * counter, or 0 if the map contains no mapping for this key.\n\t * \n\t * @param key\n\t *            the key whose associated count is to be returned.\n\t * \n\t * @return the count to which this map maps the specified key, or 0 if the\n\t *         map contains no mapping for this key.\n\t */\n        public int getCount(T key)\n        {\n            int value = counter[key];\n            if (value == null)\n            {\n                return 0;\n            }\n            return value;\n        }\n\n        /**\n\t * Increments the count to which the specified key is mapped in this\n\t * frequency counter, or puts 1 if the map contains no mapping for this key.\n\t * \n\t * @param key\n\t *            the key whose associated count is to be returned.\n\t */\n        public void incrementFor(T key)\n        {\n            int value = counter[key];\n            if(value == null)\n            {\n                counter.Add(key, 1);\n            }\n            else\n            {\n                counter.Add(key, value + 1);\n            }\n            // Keep track of the total\n            total++;\n        }\n\n        /**\n\t * Returns the count to which the specified key is mapped in this frequency\n\t * counter, divided by the total of all counts.\n\t * \n\t * @param key\n\t *            the key whose associated count is to be divided.\n    \t * \n    \t * @return the count to which this map maps the specified key, divided by\n    \t *         the total count.\n    \t */\n        public Double probabilityOf(T key)\n        {\n            int value = getCount(key);\n            if (value == 0)\n            {\n                return 0.0;\n            }\n            else\n            {\n                Double total = 0.0;\n                foreach (T k in counter.Keys)\n                {\n                    total += getCount(k);\n                }\n                return value / total;\n            }\n        }\n\n        /**\n\t * \n\t * @return a set of objects for which frequency counts have been recorded.\n    \t */\n        public HashSet<T> getStates()\n        {\n            return new HashSet<T>(counter.Keys);\n        }\n\n        /**\n\t * Remove all the currently recorded frequency counts.\n\t */\n        public void clear()\n        {\n            counter.Clear();\n            total = 0;\n        }\n\n        public String toString()\n        {\n            return counter.ToString();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/util/Interval.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * Basic supports for Intervals.\n     * \n     * @see <a href=\"http://en.wikipedia.org/wiki/Interval_%28mathematics%29\"\n     *      >Interval</a>\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n    public class Interval<C>\n    {\n\tprivate IComparable<C> lower = null;\n\tprivate bool lowerInclusive = true;\n\tprivate IComparable<C> upper = null;\n\tprivate bool upperInclusive = true;\n\n\tpublic Interval()\n\t{\n\n\t}\n\n\t/**\n\t * Constructs a closed interval from the two specified end points.\n\t * \n\t * @param lower\n\t *            the lower end point of the interval\n\t * @param upper\n\t *            the upper end point of the interval\n\t */\n\tpublic Interval(IComparable<C> lower, IComparable<C> upper)\n\t{\n\t    setLower(lower);\n\t    setUpper(upper);\n\t}\n\n\t/**\n\t * Constructs an interval from the two specified end points.\n\t * \n\t * @param lower\n\t *            the lower end point of the interval\n\t * @param lowerInclusive\n\t *            wether or not the lower end of the interval is inclusive of\n\t *            its value.\n\t * @param upper\n\t *            the upper end point of the interval\n\t * @param upperInclusive\n\t *            whether or not the upper end of the interval is inclusive of\n\t *            its value.\n\t */\n\tpublic Interval(IComparable<C> lower, bool lowerInclusive,\n\t\t\tIComparable<C> upper, bool upperInclusive)\n\t{\n\t    setLower(lower);\n\t    setLowerInclusive(lowerInclusive);\n\t    setUpper(upper);\n\t    setUpperInclusive(upperInclusive);\n\t}\n\n\t/**\n\t * Returns <code>true</code> if the specified object is between the end\n\t * points of this interval.\n\t * \n\t * @return <code>true</code> if the specified value is between the end\n\t *         points of this interval.\n\t */\n\tpublic bool isInInterval(C o)\n\t{\n\t    if(null == lower || null == upper)\n\t    {\n\t\treturn false;\n\t    }\n\n\t    bool In = true;\n\n\t    if (isLowerInclusive())\n\t    {\n\t\tIn = lower.CompareTo(o) <= 0;\n\t    }\n\t    else\n\t    {\n\t\tIn = lower.CompareTo(o) < 0;\n\t    }\n\n\t    if (In)\n\t    {\n\t\tif (isUpperInclusive())\n\t\t{\n\t\t    In = upper.CompareTo(o) >= 0;\n\t\t}\n\t\telse\n\t\t{\n\t\t    In = upper.CompareTo(o) > 0;\n\t\t}\n\t    }\n\t    return In;\n\t}\n\n\t/**\n\t * Returns <code>true</code> if this interval is lower inclusive.\n\t * \n\t * @return <code>true</code> if this interval is lower inclusive.\n\t */\n\tpublic bool isLowerInclusive()\n\t{\n\t    return lowerInclusive;\n\t}\n\n\t/**\n\t * Returns <code>true</code> if this interval is not lower inclusive.\n\t * \n\t * @return <code>true</code> if this interval is not lower inclusive.\n\t */\n\tpublic bool isLowerExclusive()\n\t{\n\t    return !lowerInclusive;\n\t}\n\n\t/**\n\t * Sets the interval to lower inclusive or lower exclusive.\n\t * \n\t * @param inclusive\n\t *            <code>true</code> represents lower inclusive and\n\t *            <code>false</code> represents lower exclusive.\n\t */\n\tpublic void setLowerInclusive(bool inclusive)\n\t{\n\t    this.lowerInclusive = inclusive;\n\t}\n\n\t/**\n\t * Sets the interval to lower exclusive or lower inclusive.\n\t * \n\t * @param exclusive\n\t *            <code>true</code> represents lower exclusive and\n\t *            <code>false</code> represents lower inclusive.\n\t */\n\tpublic void setLowerExclusive(bool exclusive)\n\t{\n\t    this.lowerInclusive = !exclusive;\n\t}\n\n\t/**\n\t * Returns the lower end point of the interval.\n\t * \n\t * @return the lower end point of the interval.\n\t */\n\tpublic IComparable<C> getLower()\n\t{\n\t    return lower;\n\t}\n\n\t/**\n\t * Sets the lower end point of the interval.\n\t * \n\t * @param lower\n\t *            the lower end point of the interval\n\t */\n\tpublic void setLower(IComparable<C> lower)\n\t{\n\t    this.lower = lower;\n\t}\n\n\t/**\n\t * Returns <code>true</code> if this interval is upper inclusive.\n\t * \n\t * @return <code>true</code> if this interval is upper inclusive.\n\t */\n\tpublic bool isUpperInclusive()\n\t{\n\t    return upperInclusive;\n\t}\n\n\t/**\n\t * Returns <code>true</code> if this interval is upper exclusive.\n\t * \n\t * @return <code>true</code> if this interval is upper exclusive.\n\t */\n\tpublic bool isUpperExclusive()\n\t{\n\t    return !upperInclusive;\n\t}\n\n\t/**\n\t * Sets the interval to upper inclusive or upper exclusive.\n\t * \n\t * @param inclusive\n\t *            <code>true</code> represents upper inclusive and\n\t *            <code>false</code> represents upper exclusive.\n\t */\n\tpublic void setUpperInclusive(bool inclusive)\n\t{\n\t    this.upperInclusive = inclusive;\n\t}\n\n\t/**\n\t * Sets the interval to upper exclusive or upper inclusive.\n\t * \n\t * @param exclusive\n\t *            <code>true</code> represents upper exclusive and\n\t *            <code>false</code> represents upper inclusive.\n\t */\n\tpublic void setUpperExclusive(bool exclusive)\n\t{\n\t    this.upperInclusive = !exclusive;\n\t}\n\n\t/**\n\t * Returns the upper end point of the interval.\n\t * \n\t * @return the upper end point of the interval.\n\t */\n\tpublic IComparable<C> getUpper()\n\t{\n\t    return upper;\n\t}\n\n\t/**\n\t * Sets the upper end point of the interval.\n\t * \n\t * @param upper\n\t *            the upper end point of the interval.\n\t */\n\tpublic void setUpper(IComparable<C> upper)\n\t{\n\t    this.upper = upper;\n\t}\n\n\tpublic System.String toString()\n\t{\n\t    return (lowerInclusive ? \"[\" : \"(\") + lower + \", \" + upper\n\t\t\t    + (upperInclusive ? \"]\" : \")\");\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/util/LUDecomposition.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * LU Decomposition.\n     * <P>\n     * For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n unit\n     * lower triangular matrix L, an n-by-n upper triangular matrix U, and a\n     * permutation vector piv of length m so that A(piv,:) = L*U. If m < n, then L\n     * is m-by-m and U is m-by-n.\n     * <P>\n     * The LU decompostion with pivoting always exists, even if the matrix is\n     * singular, so the constructor will never fail. The primary use of the LU\n     * decomposition is in the solution of square systems of simultaneous linear\n     * equations. This will fail if isNonsingular() returns false.\n     */\n     public class LUDecomposition\n    {\n\tprivate const long serialVersionUID = 1L;\n\n\t/*\n         * ------------------------ Class variables ------------------------\n         */\n\n\t/**\n         * Array for internal storage of decomposition.\n         * \n         * @serial internal array storage.\n         */\n\tprivate double[][] LU;\n\n\t/**\n         * Row and column dimensions, and pivot sign.\n         * \n         * @serial column dimension.\n         * @serial row dimension.\n         * @serial pivot sign.\n         */\n\tprivate int m, n;\n\n\tprivate int pivsign;\n\n\t/**\n         * Internal storage of pivot vector.\n         * \n         * @serial pivot vector.\n         */\n\tprivate int[] piv;\n\n\t/*\n         * ------------------------ Constructor ------------------------\n         */\n\n\t/**\n         * LU Decomposition, a structure to access L, U and piv.\n         * \n         * @param A\n         *            Rectangular matrix\n         */\n\tpublic LUDecomposition(Matrix A)\n\t{\n\n\t    // Use a \"left-looking\", dot-product, Crout/Doolittle algorithm.\n\n\t    LU = A.getArrayCopy();\n\t    m = A.getRowDimension();\n\t    n = A.getColumnDimension();\n\t    piv = new int[m];\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tpiv[i] = i;\n\t    }\n\t    pivsign = 1;\n\t    double[] LUrowi;\n\t    double[] LUcolj = new double[m];\n\n\t    // Outer loop.\n\n\t    for (int j = 0; j < n; j++)\n\t    {\n\n\t\t// Make a copy of the j-th column to localize references.\n\n\t\tfor (int i = 0; i < m; i++)\n\t\t{\n\t\t    LUcolj[i] = LU[i][j];\n\t\t}\n\n\t\t// Apply previous transformations.\n\n\t\tfor (int i = 0; i < m; i++)\n\t\t{\n\t\t    LUrowi = LU[i];\n\n\t\t    // Most of the time is spent in the following dot product.\n\n\t\t    int kmax = Math.Min(i, j);\n\t\t    double s = 0.0;\n\t\t    for (int k = 0; k < kmax; k++)\n\t\t    {\n\t\t\ts += LUrowi[k] * LUcolj[k];\n\t\t    }\n\n\t\t    LUrowi[j] = LUcolj[i] -= s;\n\t\t}\n\n\t\t// Find pivot and exchange if necessary.\n\n\t\tint p = j;\n\t\tfor (int i = j + 1; i < m; i++)\n\t\t{\n\t\t    if (Math.Abs(LUcolj[i]) > Math.Abs(LUcolj[p]))\n\t\t    {\n\t\t\tp = i;\n\t\t    }\n\t\t}\n\t\tif (p != j)\n\t\t{\n\t\t    for (int k = 0; k < n; k++)\n\t\t    {\n\t\t\tdouble t = LU[p][k];\n\t\t\tLU[p][k] = LU[j][k];\n\t\t\tLU[j][k] = t;\n\t\t    }\n\t\t    int k2 = piv[p];\n\t\t    piv[p] = piv[j];\n\t\t    piv[j] = k2;\n\t\t    pivsign = -pivsign;\n\t\t}\n\n\t\t// Compute multipliers.\n\n\t\tif (j < m & LU[j][j] != 0.0)\n\t\t{\n\t\t    for (int i = j + 1; i < m; i++)\n\t\t    {\n\t\t\tLU[i][j] /= LU[j][j];\n\t\t    }\n\t\t}\n\t    }\n\t}\n\n\t/*\n         * ------------------------ Temporary, experimental code.\n         * ------------------------\\\n         * \n         * \\ LU Decomposition, computed by Gaussian elimination. <P> This\n         * constructor computes L and U with the \"daxpy\"-based elimination algorithm\n         * used in LINPACK and MATLAB. In Java, we suspect the dot-product, Crout\n         * algorithm will be faster. We have temporarily included this constructor\n         * until timing experiments confirm this suspicion. <P> @param A Rectangular\n         * matrix @param linpackflag Use Gaussian elimination. Actual value ignored.\n         * \n         * @return Structure to access L, U and piv. \\\n         * \n         * public LUDecomposition (Matrix A, int linpackflag) { // Initialize. LU =\n         * A.getArrayCopy(); m = A.getRowDimension(); n = A.getColumnDimension();\n         * piv = new int[m]; for (int i = 0; i < m; i++) { piv[i] = i; } pivsign =\n         * 1; // Main loop. for (int k = 0; k < n; k++) { // Find pivot. int p = k;\n         * for (int i = k+1; i < m; i++) { if (Math.abs(LU[i][k]) >\n         * Math.abs(LU[p][k])) { p = i; } } // Exchange if necessary. if (p != k) {\n         * for (int j = 0; j < n; j++) { double t = LU[p][j]; LU[p][j] = LU[k][j];\n         * LU[k][j] = t; } int t = piv[p]; piv[p] = piv[k]; piv[k] = t; pivsign =\n         * -pivsign; } // Compute multipliers and eliminate k-th column. if\n         * (LU[k][k] != 0.0) { for (int i = k+1; i < m; i++) { LU[i][k] /= LU[k][k];\n         * for (int j = k+1; j < n; j++) { LU[i][j] -= LU[i][k]LU[k][j]; } } } } } \\\n         * ------------------------ End of temporary code. ------------------------\n         */\n\n\t/*\n         * ------------------------ Public Methods ------------------------\n         */\n\n\t/**\n         * Is the matrix nonsingular?\n         * \n         * @return true if U, and hence A, is nonsingular.\n         */\n\tpublic bool isNonsingular()\n\t{\n\t    for (int j = 0; j < n; j++)\n\t    {\n\t\tif (LU[j][j] == 0)\n\t\t    return false;\n\t    }\n\t    return true;\n\t}\n\n\t/**\n         * Return lower triangular factor\n         * \n         * @return L\n         */\n\tpublic Matrix getL()\n\t{\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] L = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    if (i > j)\n\t\t    {\n\t\t\tL[i][j] = LU[i][j];\n\t\t    }\n\t\t    else if (i == j)\n\t\t    {\n\t\t\tL[i][j] = 1.0;\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\tL[i][j] = 0.0;\n\t\t    }\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n         * Return upper triangular factor\n         * \n         * @return U\n         */\n\tpublic Matrix getU()\n\t{\n\t    Matrix X = new Matrix(n, n);\n\t    double[][] U = X.getArray();\n\t    for (int i = 0; i < n; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    if (i <= j)\n\t\t    {\n\t\t\tU[i][j] = LU[i][j];\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\tU[i][j] = 0.0;\n\t\t    }\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n         * Return pivot permutation vector\n         * \n         * @return piv\n         */\n\tpublic int[] getPivot()\n\t{\n\t    int[] p = new int[m];\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tp[i] = piv[i];\n\t    }\n\t    return p;\n\t}\n\n\t/**\n         * Return pivot permutation vector as a one-dimensional double array\n         * \n         * @return (double) piv\n         */\n\tpublic double[] getDoublePivot()\n\t{\n\t    double[] vals = new double[m];\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tvals[i] = piv[i];\n\t    }\n\t    return vals;\n\t}\n\n\t/**\n         * Determinant\n         * \n         * @return det(A)\n         * @exception IllegalArgumentException\n         *                Matrix must be square\n         */\n\tpublic double det()\n\t{\n\t    if (m != n)\n\t    {\n\t\tthrow new ArgumentException(\"Matrix must be square.\");\n\t    }\n\t    double d = pivsign;\n\t    for (int j = 0; j < n; j++)\n\t    {\n\t\td *= LU[j][j];\n\t    }\n\t    return d;\n\t}\n\n\t/**\n         * Solve A*X = B\n         * \n         * @param B\n         *            A Matrix with as many rows as A and any number of columns.\n         * @return X so that L*U*X = B(piv,:)\n         * @exception IllegalArgumentException\n         *                Matrix row dimensions must agree.\n         * @exception ApplicationException\n         *                Matrix is singular.\n         */\n\tpublic Matrix solve(Matrix B)\n\t{\n\t    if (B.getRowDimension() != m)\n\t    {\n\t\tthrow new ArgumentException(\n\t\t\t\"Matrix row dimensions must agree.\");\n\t    }\n\t    if (!this.isNonsingular())\n\t    {\n\t\tthrow new ApplicationException(\"Matrix is singular.\");\n\t    }\n\n\t    // Copy right hand side with pivoting\n\t    int nx = B.getColumnDimension();\n\t    Matrix Xmat = B.getMatrix(piv, 0, nx - 1);\n\t    double[][] X = Xmat.getArray();\n\n\t    // Solve L*Y = B(piv,:)\n\t    for (int k = 0; k < n; k++)\n\t    {\n\t\tfor (int i = k + 1; i < n; i++)\n\t\t{\n\t\t    for (int j = 0; j < nx; j++)\n\t\t    {\n\t\t\tX[i][j] -= X[k][j] * LU[i][k];\n\t\t    }\n\t\t}\n\t    }\n\t    // Solve U*X = Y;\n\t    for (int k = n - 1; k >= 0; k--)\n\t    {\n\t\tfor (int j = 0; j < nx; j++)\n\t\t{\n\t\t    X[k][j] /= LU[k][k];\n\t\t}\n\t\tfor (int i = 0; i < k; i++)\n\t\t{\n\t\t    for (int j = 0; j < nx; j++)\n\t\t    {\n\t\t\tX[i][j] -= X[k][j] * LU[i][k];\n\t\t    }\n\t\t}\n\t    }\n\t    return Xmat;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/util/LabeledGraph.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * Represents a directed labeled graph. Vertices are represented by their unique\n     * labels and labeled edges by means of nested hashtables. Variant of class\n     * {@code aima.util.Table}. This version is more dynamic, it requires no\n     * initialization and can add new items whenever needed.\n     * \n     * @author R. Lunde\n     * @author Mike Stampone\n     */\n    public class LabeledGraph<VertexLabelType, EdgeLabelType>\n    {\n\t/**\n\t * Lookup for edge label information. Contains an entry for every vertex\n\t * label.\n\t */\n\tprivate readonly Dictionary<VertexLabelType, Dictionary<VertexLabelType, EdgeLabelType>> globalEdgeLookup;\n\t/** List of the labels of all vertices within the graph. */\n\tprivate readonly List<VertexLabelType> vertexLabels;\n\n\t/** Creates a new empty graph. */\n\tpublic LabeledGraph()\n\t{\n\t    globalEdgeLookup = new Dictionary<VertexLabelType, Dictionary<VertexLabelType, EdgeLabelType>>();\n\t    vertexLabels = new List<VertexLabelType>();\n\t}\n\n\t/**\n\t * Adds a new vertex to the graph if it is not already present.\n\t * \n\t * @param v\n\t *            the vertex to add\n\t */\n\tpublic void addVertex(VertexLabelType v)\n\t{\n\t    checkForNewVertex(v);\n\t}\n\n\t/**\n\t * Adds a directed labeled edge to the graph. The end points of the edge are\n\t * specified by vertex labels. New vertices are automatically identified and\n\t * added to the graph.\n\t * \n\t * @param from\n\t *            the first vertex of the edge\n\t * @param to\n\t *            the second vertex of the edge\n\t * @param el\n\t *            an edge label\n\t */\n\tpublic void set(VertexLabelType from, VertexLabelType to, EdgeLabelType el)\n\t{\n\t    Dictionary<VertexLabelType, EdgeLabelType> localEdgeLookup = checkForNewVertex(from);\n\t    localEdgeLookup.Add(to, el);\n\t    checkForNewVertex(to);\n\t}\n\n\t/** Handles new vertices. */\n\tprivate Dictionary<VertexLabelType, EdgeLabelType> checkForNewVertex(\n\t\t\tVertexLabelType v)\n\t{\n\t    Dictionary<VertexLabelType, EdgeLabelType> result = globalEdgeLookup[v];\n\t    if (result == null)\n\t    {\n\t\tresult = new Dictionary<VertexLabelType, EdgeLabelType>();\n\t\tglobalEdgeLookup.Add(v, result);\n\t\tvertexLabels.Add(v);\n\t    }\n\t    return result;\n\t}\n\n\t/**\n\t * Removes an edge from the graph.\n\t * \n\t * @param from\n\t *            the first vertex of the edge\n\t * @param to\n\t *            the second vertex of the edge\n\t */\n\tpublic void remove(VertexLabelType from, VertexLabelType to)\n\t{\n\t    Dictionary<VertexLabelType, EdgeLabelType> localEdgeLookup = globalEdgeLookup[from];\n\t    if (localEdgeLookup != null)\n\t\tlocalEdgeLookup.Remove(to);\n\t}\n\n\t/**\n\t * Returns the label of the edge between the specified vertices, or null if\n\t * there is no edge between them.\n\t * \n\t * @param from\n\t *            the first vertex of the ege\n\t * @param to\n\t *            the second vertex of the edge\n\t * \n\t * @return the label of the edge between the specified vertices, or null if\n\t *         there is no edge between them.\n\t */\n\tpublic EdgeLabelType get(VertexLabelType from, VertexLabelType to)\n\t{\n\t    Dictionary<VertexLabelType, EdgeLabelType> localEdgeLookup = globalEdgeLookup[from];\n\t    return localEdgeLookup == null ? default(EdgeLabelType) : localEdgeLookup[to];\n\t}\n\n\t/**\n\t * Returns the labels of those vertices which can be obtained by following\n\t * the edges starting at the specified vertex.\n\t */\n\tpublic List<VertexLabelType> getSuccessors(VertexLabelType v)\n\t{\n\t    List<VertexLabelType> result = new List<VertexLabelType>();\n\t    Dictionary<VertexLabelType, EdgeLabelType> localEdgeLookup = globalEdgeLookup[v];\n\t    if (localEdgeLookup != null)\n\t\tresult.AddRange(localEdgeLookup.Keys);\n\t    return result;\n\t}\n\n\t/** Returns the labels of all vertices within the graph. */\n\tpublic List<VertexLabelType> getVertexLabels()\n\t{\n\t    return vertexLabels;\n\t}\n\n\t/** Checks whether the given label is the label of one of the vertices. */\n\tpublic bool isVertexLabel(VertexLabelType v)\n\t{\n\t    return globalEdgeLookup[v] != null;\n\t}\n\n\t/** Removes all vertices and all edges from the graph. */\n\tpublic void clear()\n\t{\n\t    vertexLabels.Clear();\n\t    globalEdgeLookup.Clear();\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/util/LinkedHashSet.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    public class LinkedHashSet<T> : ISet<T> {\n\n    private readonly IDictionary<T, LinkedListNode<T>> dict;\n    private readonly LinkedList<T> list;\n\n    public LinkedHashSet(int initialCapacity) {\n        this.dict = new Dictionary<T,LinkedListNode<T>>(initialCapacity);\n        this.list = new LinkedList<T>();\n    }\n\n    public LinkedHashSet() {\n        this.dict = new Dictionary<T,LinkedListNode<T>>();\n        this.list = new LinkedList<T>();\n    }\n\n    public LinkedHashSet(IEnumerable<T> e) : this() {\n        addEnumerable(e);\n    }\n\n    public LinkedHashSet(int initialCapacity, IEnumerable<T> e) : this(initialCapacity) {\n        addEnumerable(e);\n    }\n\n    private void addEnumerable(IEnumerable<T> e) {\n        foreach (T t in e) {\n            Add(t);\n        }\n    }\n\n    // ISet implementation\n\n    public bool Add(T item) {\n        if (this.dict.ContainsKey(item)) {\n            return false;\n        }\n        LinkedListNode<T> node = this.list.AddLast(item);\n        this.dict[item] = node;\n        return true;\n    }\n\n    public void ExceptWith(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        foreach (T t in other) {\n            Remove(t);\n        }\n    }\n\n    public void IntersectWith(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        T[] ts = new T[Count];\n        CopyTo(ts, 0);\n        foreach (T t in ts) {\n            if (!System.Linq.Enumerable.Contains(other, t)) {\n                Remove(t);\n            }\n        }\n    }\n\n    public bool IsProperSubsetOf(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        int contains = 0;\n        int noContains = 0;\n        foreach (T t in other) {\n            if (Contains(t)) {\n                contains++;\n            } else {\n                noContains++;\n            }\n        }\n        return contains == Count && noContains > 0;\n    }\n\n    public bool IsProperSupersetOf(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        int otherCount = System.Linq.Enumerable.Count(other);\n        if (Count <= otherCount) {\n            return false;\n        }\n        int contains = 0;\n        int noContains = 0;\n        foreach (T t in this) {\n            if (System.Linq.Enumerable.Contains(other, t)) {\n                contains++;\n            } else {\n                noContains++;\n            }\n        }\n        return contains == otherCount && noContains > 0;\n    }\n\n    public bool IsSubsetOf(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        foreach (T t in this) {\n            if (!System.Linq.Enumerable.Contains(other, t)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    public bool IsSupersetOf(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        foreach (T t in other) {\n            if (!Contains(t)) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    public bool Overlaps(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        foreach (T t in other) {\n            if (Contains(t)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public bool SetEquals(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        int otherCount = System.Linq.Enumerable.Count(other);\n        if (Count != otherCount) {\n            return false;\n        }\n        return IsSupersetOf(other);\n    }\n\n    public void SymmetricExceptWith(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        T[] ts = new T[Count];\n        CopyTo(ts, 0);\n        HashSet<T> otherList = new HashSet<T>(other);\n        foreach (T t in ts) {\n            if (otherList.Contains(t)) {\n                Remove(t);\n                otherList.Remove(t);\n            }\n        }\n        foreach (T t in otherList) {\n            Add(t);\n        }\n    }\n\n    public void UnionWith(IEnumerable<T> other) {\n        if (other == null) {\n            throw new ArgumentNullException(\"other cannot be null\");\n        }\n        foreach (T t in other) {\n            Add(t);\n        }\n    }\n\n    // ICollection<T> implementation\n    \n    public int Count {\n        get {\n            return this.dict.Count;\n        }\n    }\n\n    public bool IsReadOnly {\n        get {\n            return this.dict.IsReadOnly;\n        }\n    }\n\n    void ICollection<T>.Add(T item) {\n        Add(item);\n    }\n\n    public void Clear() {\n        this.dict.Clear();\n        this.list.Clear();\n    }\n\n    public bool Contains(T item) {\n        return this.dict.ContainsKey(item);\n    }\n\n    public void CopyTo(T[] array, int arrayIndex) {\n        this.list.CopyTo(array, arrayIndex);\n    }\n\n    public bool Remove(T item) {\n        LinkedListNode<T> node;\n        if (!this.dict.TryGetValue(item, out node)) {\n            return false;\n        }\n        this.dict.Remove(item);\n        this.list.Remove(node);\n        return true;\n    }\n\n    // IEnumerable<T> implementation\n    \n    public IEnumerator<T> GetEnumerator() {\n        return this.list.GetEnumerator();\n    }\n\n    // IEnumerable implementation\n    \n    IEnumerator IEnumerable.GetEnumerator() {\n        return this.list.GetEnumerator();\n    }\n\n}\n}"
  },
  {
    "path": "aima-csharp/util/Matrix.cs",
    "content": "using System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.IO;\n\nnamespace aima.core.util\n{\n    /**\n     * Jama = Java Matrix class.\n     * <P>\n     * The Java Matrix Class provides the fundamental operations of numerical linear\n     * algebra. Various constructors create Matrices from two dimensional arrays of\n     * double precision floating point numbers. Various \"gets\" and \"sets\" provide\n     * access to submatrices and matrix elements. Several methods implement basic\n     * matrix arithmetic, including matrix addition and multiplication, matrix\n     * norms, and element-by-element array operations. Methods for reading and\n     * printing matrices are also included. All the operations in this version of\n     * the Matrix Class involve real matrices. Complex matrices may be handled in a\n     * future version.\n     * <P>\n     * Five fundamental matrix decompositions, which consist of pairs or triples of\n     * matrices, permutation vectors, and the like, produce results in five\n     * decomposition classes. These decompositions are accessed by the Matrix class\n     * to compute solutions of simultaneous linear equations, determinants, inverses\n     * and other matrix functions. The five decompositions are:\n     * <P>\n     * <UL>\n     * <LI>Cholesky Decomposition of symmetric, positive definite matrices.\n     * <LI>LU Decomposition of rectangular matrices.\n     * <LI>QR Decomposition of rectangular matrices.\n     * <LI>Singular Value Decomposition of rectangular matrices.\n     * <LI>Eigenvalue Decomposition of both symmetric and nonsymmetric square\n     * matrices.\n     * </UL>\n     * <DL>\n     * <DT><B>Example of use:</B></DT>\n     * <P>\n     * <DD>Solve a linear system A x = b and compute the residual norm, ||b - A x||.\n     * <P>\n     * \n     * <PRE>\n     * double[][] vals = { { 1., 2., 3 }, { 4., 5., 6. }, { 7., 8., 10. } };\n     * Matrix A = new Matrix(vals);\n     * Matrix b = Matrix.random(3, 1);\n     * Matrix x = A.solve(b);\n     * Matrix r = A.times(x).minus(b);\n     * double rnorm = r.normInf();\n     * </PRE>\n     * \n     * </DD>\n     * </DL>\n     * \n     * @author The MathWorks, Inc. and the National Institute of Standards and\n     *         Technology.\n     * @version 5 August 1998\n     */\n    public class Matrix\n    {\n\tprivate static readonly long serialVersionUID = 1L;\n\n\t/*\n\t * ------------------------ Class variables ------------------------\n\t */\n\n\t/**\n\t * Array for internal storage of elements.\n\t * \n\t * @serial internal array storage.\n\t */\n\tprivate readonly double[][] A;\n\n\t/**\n\t * Row and column dimensions.\n\t * \n\t * @serial row dimension.\n\t * @serial column dimension.\n\t */\n\tprivate readonly int m, n;\n\n\t/*\n\t * ------------------------ Constructors ------------------------\n\t */\n\n\t/** Construct a diagonal Matrix from the given List of doubles */\n\tpublic static Matrix createDiagonalMatrix(List<Double> values)\n\t{\n\t    Matrix m = new Matrix(values.Count, values.Count, 0);\n\t    for (int i = 0; i < values.Count; i++)\n\t    {\n\t\tm.set(i, i, values[i]);\n\t    }\n\t    return m;\n\t}\n\n\t/**\n\t * Construct an m-by-n matrix of zeros.\n\t * \n\t * @param m\n\t *            Number of rows.\n\t * @param n\n\t *            Number of colums.\n\t */\n\n\tpublic Matrix(int m, int n)\n\t{\n\t    this.m = m;\n\t    this.n = n;\n\t    A = new double[m][];\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tA[i] = new double[n];\n\t    }\n\t}\n\n\t/**\n\t * Construct an m-by-n constant matrix.\n\t * \n\t * @param m\n\t *            Number of rows.\n\t * @param n\n\t *            Number of colums.\n\t * @param s\n\t *            Fill the matrix with this scalar value.\n\t */\n\n\tpublic Matrix(int m, int n, double s)\n\t{\n\t    this.m = m;\n\t    this.n = n;\n\t    A = new double[m][];\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tA[i] = new double[n];\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    A[i][j] = s;\n\t\t}\n\t    }\n\t}\n\n\t/**\n\t * Construct a matrix from a 2-D array.\n\t * \n\t * @param A\n\t *            Two-dimensional array of doubles.\n\t * @exception IllegalArgumentException\n\t *                All rows must have the same length\n\t * @see #constructWithCopy\n\t */\n\n\tpublic Matrix(double[][] A)\n\t{\n\t    m = A.Length;\n\t    n = A[0].Length;\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tif (A[i].Length != n)\n\t\t{\n\t\t    throw new ArgumentOutOfRangeException(\n\t\t\t\t    \"All rows must have the same length.\");\n\t\t}\n\t    }\n\t    this.A = A;\n\t}\n\n\t/**\n\t * Construct a matrix quickly without checking arguments.\n\t * \n\t * @param A\n\t *            Two-dimensional array of doubles.\n\t * @param m\n\t *            Number of rows.\n\t * @param n\n\t *            Number of colums.\n\t */\n\n\tpublic Matrix(double[][] A, int m, int n)\n\t{\n\t    this.A = A;\n\t    this.m = m;\n\t    this.n = n;\n\t}\n\n\t/**\n\t * Construct a matrix from a one-dimensional packed array\n\t * \n\t * @param vals\n\t *            One-dimensional array of doubles, packed by columns (ala\n\t *            Fortran).\n\t * @param m\n\t *            Number of rows.\n\t * @exception IllegalArgumentException\n\t *                Array length must be a multiple of m.\n\t */\n\n\tpublic Matrix(double[] vals, int m)\n\t{\n\t    this.m = m;\n\t    n = (m != 0 ? vals.Length / m : 0);\n\t    if (m * n != vals.Length)\n\t    {\n\t\tthrow new ArgumentOutOfRangeException(\n\t\t\t\t\"Array length must be a multiple of m.\");\n\t    }\n\t    A = new double[m][];\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    A[i][j] = vals[i + j * m];\n\t\t}\n\t    }\n\t}\n\n\t/*\n\t * ------------------------ Public Methods ------------------------\n\t */\n\n\t/**\n\t * Construct a matrix from a copy of a 2-D array.\n\t * \n\t * @param A\n\t *            Two-dimensional array of doubles.\n\t * @exception IllegalArgumentException\n\t *                All rows must have the same length\n\t */\n\n\tpublic static Matrix constructWithCopy(double[][] A)\n\t{\n\t    int m = A.Length;\n\t    int n = A[0].Length;\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tif (A[i].Length != n)\n\t\t{\n\t\t    throw new ArgumentOutOfRangeException(\n\t\t\t\t    \"All rows must have the same length.\");\n\t\t}\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * Make a deep copy of a matrix\n\t */\n\n\tpublic Matrix copy()\n\t{\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * Clone the Matrix object.\n\t */\n\n\tpublic Object clone()\n\t{\n\t    return this.copy();\n\t}\n\n\t/**\n\t * Access the internal two-dimensional array.\n\t * \n\t * @return Pointer to the two-dimensional array of matrix elements.\n\t */\n\n\tpublic double[][] getArray()\n\t{\n\t    return A;\n\t}\n\n\t/**\n\t * Copy the internal two-dimensional array.\n\t * \n\t * @return Two-dimensional array copy of matrix elements.\n\t */\n\n\tpublic double[][] getArrayCopy()\n\t{\n\t    double[][] C = new double[m][];\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tC[i] = new double[n];\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = A[i][j];\n\t\t}\n\t    }\n\t    return C;\n\t}\n\n\t/**\n\t * Make a one-dimensional column packed copy of the internal array.\n\t * \n\t * @return Matrix elements packed in a one-dimensional array by columns.\n\t */\n\n\tpublic double[] getColumnPackedCopy()\n\t{\n\t    double[] vals = new double[m * n];\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    vals[i + j * m] = A[i][j];\n\t\t}\n\t    }\n\t    return vals;\n\t}\n\n\t/**\n\t * Make a one-dimensional row packed copy of the internal array.\n\t * \n\t * @return Matrix elements packed in a one-dimensional array by rows.\n\t */\n\n\tpublic double[] getRowPackedCopy()\n\t{\n\t    double[] vals = new double[m * n];\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    vals[i * n + j] = A[i][j];\n\t\t}\n\t    }\n\t    return vals;\n\t}\n\n\t/**\n\t * Get row dimension.\n\t * \n\t * @return m, the number of rows.\n\t */\n\n\tpublic int getRowDimension()\n\t{\n\t    return m;\n\t}\n\n\t/**\n\t * Get column dimension.\n\t * \n\t * @return n, the number of columns.\n\t */\n\n\tpublic int getColumnDimension()\n\t{\n\t    return n;\n\t}\n\n\t/**\n\t * Get a single element.\n\t * \n\t * @param i\n\t *            Row index.\n\t * @param j\n\t *            Column index.\n\t * @return A(i,j)\n\t * @exception ArrayIndexOutOfBoundsException\n\t */\n\n\tpublic double get(int i, int j)\n\t{\n\t    return A[i][j];\n\t}\n\n\t/**\n\t * Get a submatrix.\n\t * \n\t * @param i0\n\t *            Initial row index\n\t * @param i1\n\t *            Final row index\n\t * @param j0\n\t *            Initial column index\n\t * @param j1\n\t *            Final column index\n\t * @return A(i0:i1,j0:j1)\n\t * @exception ArrayIndexOutOfBoundsException\n\t *                Submatrix indices\n\t */\n\n\tpublic Matrix getMatrix(int i0, int i1, int j0, int j1)\n\t{\n\t    Matrix X = new Matrix(i1 - i0 + 1, j1 - j0 + 1);\n\t    double[][] B = X.getArray();\n\t    for (int i = i0; i <= i1; i++)\n\t    {\n\t\tfor (int j = j0; j <= j1; j++)\n\t\t{\n\t\t    B[i - i0][j - j0] = A[i][j];\n\t\t}\n\t    }\n\n\t    return X;\n\t}\n\n\t/**\n\t * Get a submatrix.\n\t * \n\t * @param r\n\t *            Array of row indices.\n\t * @param c\n\t *            Array of column indices.\n\t * @return A(r(:),c(:))\n\t * @exception ArrayIndexOutOfBoundsException\n\t *                Submatrix indices\n\t */\n\n\tpublic Matrix getMatrix(int[] r, int[] c)\n\t{\n\t    Matrix X = new Matrix(r.Length, c.Length);\n\t    double[][] B = X.getArray();\n\n\t    for (int i = 0; i < r.Length; i++)\n\t    {\n\t\tfor (int j = 0; j < c.Length; j++)\n\t\t{\n\t\t    B[i][j] = A[r[i]][c[j]];\n\t\t}\n\t    }\n\n\t    return X;\n\t}\n\n\t/**\n\t * Get a submatrix.\n\t * \n\t * @param i0\n\t *            Initial row index\n\t * @param i1\n\t *            Final row index\n\t * @param c\n\t *            Array of column indices.\n\t * @return A(i0:i1,c(:))\n\t * @exception ArrayIndexOutOfBoundsException\n\t *                Submatrix indices\n\t */\n\n\tpublic Matrix getMatrix(int i0, int i1, int[] c)\n\t{\n\t    Matrix X = new Matrix(i1 - i0 + 1, c.Length);\n\t    double[][] B = X.getArray();\n\n\t    for (int i = i0; i <= i1; i++)\n\t    {\n\t\tfor (int j = 0; j < c.Length; j++)\n\t\t{\n\t\t    B[i - i0][j] = A[i][c[j]];\n\t\t}\n\t    }\n\n\t    return X;\n\t}\n\n\t/**\n\t * Get a submatrix.\n\t * \n\t * @param r\n\t *            Array of row indices.\n\t * @param j0\n\t *            Initial column index\n\t * @param j1\n\t *            Final column index\n\t * @return A(r(:),j0:j1)\n\t * @exception ArrayIndexOutOfBoundsException\n\t *                Submatrix indices\n\t */\n\n\tpublic Matrix getMatrix(int[] r, int j0, int j1)\n\t{\n\t    Matrix X = new Matrix(r.Length, j1 - j0 + 1);\n\t    double[][] B = X.getArray();\n\n\t    for (int i = 0; i < r.Length; i++)\n\t    {\n\t\tfor (int j = j0; j <= j1; j++)\n\t\t{\n\t\t    B[i][j - j0] = A[r[i]][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * Set a single element.\n\t * \n\t * @param i\n\t *            Row index.\n\t * @param j\n\t *            Column index.\n\t * @param s\n\t *            A(i,j).\n\t * @exception ArrayIndexOutOfBoundsException\n\t */\n\n\tpublic void set(int i, int j, double s)\n\t{\n\t    A[i][j] = s;\n\t}\n\n\t/**\n\t * Set a submatrix.\n\t * \n\t * @param i0\n\t *            Initial row index\n\t * @param i1\n\t *            Final row index\n\t * @param j0\n\t *            Initial column index\n\t * @param j1\n\t *            Final column index\n\t * @param X\n\t *            A(i0:i1,j0:j1)\n\t * @exception ArrayIndexOutOfBoundsException\n\t *                Submatrix indices\n\t */\n\n\tpublic void setMatrix(int i0, int i1, int j0, int j1, Matrix X)\n\t{\n\t    for (int i = i0; i <= i1; i++)\n\t    {\n\t\tfor (int j = j0; j <= j1; j++)\n\t\t{\n\t\t    A[i][j] = X.get(i - i0, j - j0);\n\t\t}\n\t    }\n\t}\n\n\t/**\n\t * Set a submatrix.\n\t * \n\t * @param r\n\t *            Array of row indices.\n\t * @param c\n\t *            Array of column indices.\n\t * @param X\n\t *            A(r(:),c(:))\n\t * @exception ArrayIndexOutOfBoundsException\n\t *                Submatrix indices\n\t */\n\n\tpublic void setMatrix(int[] r, int[] c, Matrix X)\n\t{\n\t    for (int i = 0; i < r.Length; i++)\n\t    {\n\t\tfor (int j = 0; j < c.Length; j++)\n\t\t{\n\t\t    A[r[i]][c[j]] = X.get(i, j);\n\t\t}\n\t    }\n\t}\n\n\t/**\n\t * Set a submatrix.\n\t * \n\t * @param r\n\t *            Array of row indices.\n\t * @param j0\n\t *            Initial column index\n\t * @param j1\n\t *            Final column index\n\t * @param X\n\t *            A(r(:),j0:j1)\n\t * @exception ArrayIndexOutOfBoundsException\n\t *                Submatrix indices\n\t */\n\n\tpublic void setMatrix(int[] r, int j0, int j1, Matrix X)\n\t{\n\n\t    for (int i = 0; i < r.Length; i++)\n\t    {\n\t\tfor (int j = j0; j <= j1; j++)\n\t\t{\n\t\t    A[r[i]][j] = X.get(i, j - j0);\n\t\t}\n\t    }\n\t}\n\n\t/**\n\t * Set a submatrix.\n\t * \n\t * @param i0\n\t *            Initial row index\n\t * @param i1\n\t *            Final row index\n\t * @param c\n\t *            Array of column indices.\n\t * @param X\n\t *            A(i0:i1,c(:))\n\t * @exception ArrayIndexOutOfBoundsException\n\t *                Submatrix indices\n\t */\n\n\tpublic void setMatrix(int i0, int i1, int[] c, Matrix X)\n\t{\n\n\t    for (int i = i0; i <= i1; i++)\n\t    {\n\t\tfor (int j = 0; j < c.Length; j++)\n\t\t{\n\t\t    A[i][c[j]] = X.get(i - i0, j);\n\t\t}\n\t    }\n\t}\n\n\t/**\n\t * Matrix transpose.\n\t * \n\t * @return A'\n\t */\n\n\tpublic Matrix transpose()\n\t{\n\t    Matrix X = new Matrix(n, m);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[j][i] = A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * One norm\n\t * \n\t * @return maximum column sum.\n\t */\n\n\tpublic double norm1()\n\t{\n\t    double f = 0;\n\t    for (int j = 0; j < n; j++)\n\t    {\n\t\tdouble s = 0;\n\t\tfor (int i = 0; i < m; i++)\n\t\t{\n\t\t    s += Math.Abs(A[i][j]);\n\t\t}\n\t\tf = Math.Max(f, s);\n\t    }\n\t    return f;\n\t}\n\n\t/**\n\t * Two norm\n\t * \n\t * @return maximum singular value.\n\t */\n\n\t// public double norm2 () {\n\t// return (new SingularValueDecomposition(this).norm2());\n\t// }\n\t/**\n\t * Infinity norm\n\t * \n\t * @return maximum row sum.\n\t */\n\n\tpublic double normInf()\n\t{\n\t    double f = 0;\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tdouble s = 0;\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    s += Math.Abs(A[i][j]);\n\t\t}\n\t\tf = Math.Max(f, s);\n\t    }\n\t    return f;\n\t}\n\n\t/**\n\t * Frobenius norm\n\t * \n\t * @return sqrt of sum of squares of all elements.\n\t */\n\n\t// public double normF () {\n\t// double f = 0;\n\t// for (int i = 0; i < m; i++) {\n\t// for (int j = 0; j < n; j++) {\n\t// f = Maths.hypot(f,A[i][j]);\n\t// }\n\t// }\n\t// return f;\n\t// }\n\t/**\n\t * Unary minus\n\t * \n\t * @return -A\n\t */\n\n\tpublic Matrix uminus()\n\t{\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = -A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * C = A + B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A + B\n\t */\n\n\tpublic Matrix plus(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = A[i][j] + B.A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * A = A + B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A + B\n\t */\n\n\tpublic Matrix plusEquals(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    A[i][j] = A[i][j] + B.A[i][j];\n\t\t}\n\t    }\n\t    return this;\n\t}\n\n\t/**\n\t * C = A - B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A - B\n\t */\n\n\tpublic Matrix minus(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = A[i][j] - B.A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * A = A - B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A - B\n\t */\n\n\tpublic Matrix minusEquals(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    A[i][j] = A[i][j] - B.A[i][j];\n\t\t}\n\t    }\n\t    return this;\n\t}\n\n\t/**\n\t * Element-by-element multiplication, C = A.*B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A.*B\n\t */\n\n\tpublic Matrix arrayTimes(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = A[i][j] * B.A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * Element-by-element multiplication in place, A = A.*B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A.*B\n\t */\n\n\tpublic Matrix arrayTimesEquals(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    A[i][j] = A[i][j] * B.A[i][j];\n\t\t}\n\t    }\n\t    return this;\n\t}\n\n\t/**\n\t * Element-by-element right division, C = A./B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A./B\n\t */\n\n\tpublic Matrix arrayRightDivide(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = A[i][j] / B.A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * Element-by-element right division in place, A = A./B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A./B\n\t */\n\n\tpublic Matrix arrayRightDivideEquals(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    A[i][j] = A[i][j] / B.A[i][j];\n\t\t}\n\t    }\n\t    return this;\n\t}\n\n\t/**\n\t * Element-by-element left division, C = A.\\B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A.\\B\n\t */\n\n\tpublic Matrix arrayLeftDivide(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = B.A[i][j] / A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * Element-by-element left division in place, A = A.\\B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return A.\\B\n\t */\n\n\tpublic Matrix arrayLeftDivideEquals(Matrix B)\n\t{\n\t    checkMatrixDimensions(B);\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    A[i][j] = B.A[i][j] / A[i][j];\n\t\t}\n\t    }\n\t    return this;\n\t}\n\n\t/**\n\t * Multiply a matrix by a scalar, C = s*A\n\t * \n\t * @param s\n\t *            scalar\n\t * @return s*A\n\t */\n\n\tpublic Matrix times(double s)\n\t{\n\t    Matrix X = new Matrix(m, n);\n\t    double[][] C = X.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    C[i][j] = s * A[i][j];\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * Multiply a matrix by a scalar in place, A = s*A\n\t * \n\t * @param s\n\t *            scalar\n\t * @return replace A by s*A\n\t */\n\n\tpublic Matrix timesEquals(double s)\n\t{\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    A[i][j] = s * A[i][j];\n\t\t}\n\t    }\n\t    return this;\n\t}\n\n\t/**\n\t * Linear algebraic matrix multiplication, A * B\n\t * \n\t * @param B\n\t *            another matrix\n\t * @return Matrix product, A * B\n\t * @exception IllegalArgumentException\n\t *                Matrix inner dimensions must agree.\n\t */\n\n\tpublic Matrix times(Matrix B)\n\t{\n\t    if (B.m != n)\n\t    {\n\t\tthrow new ArgumentException(\n\t\t\t\t\"Matrix inner dimensions must agree.\");\n\t    }\n\t    Matrix X = new Matrix(m, B.n);\n\t    double[][] C = X.getArray();\n\t    double[] Bcolj = new double[n];\n\t    for (int j = 0; j < B.n; j++)\n\t    {\n\t\tfor (int k = 0; k < n; k++)\n\t\t{\n\t\t    Bcolj[k] = B.A[k][j];\n\t\t}\n\t\tfor (int i = 0; i < m; i++)\n\t\t{\n\t\t    double[] Arowi = A[i];\n\t\t    double s = 0;\n\t\t    for (int k = 0; k < n; k++)\n\t\t    {\n\t\t\ts += Arowi[k] * Bcolj[k];\n\t\t    }\n\t\t    C[i][j] = s;\n\t\t}\n\t    }\n\t    return X;\n\t}\n\n\t/**\n\t * LU Decomposition\n\t * \n\t * @return LUDecomposition\n\t * @see LUDecomposition\n\t */\n\n\tpublic LUDecomposition lu()\n\t{\n\t    return new LUDecomposition(this);\n\t}\n\n\t// /** QR Decomposition\n\t// @return QRDecomposition\n\t// @see QRDecomposition\n\t// */\n\t//\n\t// public QRDecomposition qr () {\n\t// return new QRDecomposition(this);\n\t// }\n\t//\n\t// /** Cholesky Decomposition\n\t// @return CholeskyDecomposition\n\t// @see CholeskyDecomposition\n\t// */\n\t//\n\t// public CholeskyDecomposition chol () {\n\t// return new CholeskyDecomposition(this);\n\t// }\n\t//\n\t// /** Singular Value Decomposition\n\t// @return SingularValueDecomposition\n\t// @see SingularValueDecomposition\n\t// */\n\t//\n\t// public SingularValueDecomposition svd () {\n\t// return new SingularValueDecomposition(this);\n\t// }\n\t//\n\t// /** Eigenvalue Decomposition\n\t// @return EigenvalueDecomposition\n\t// @see EigenvalueDecomposition\n\t// */\n\t//\n\t// public EigenvalueDecomposition eig () {\n\t// return new EigenvalueDecomposition(this);\n\t// }\n\n\t/**\n\t * Solve A*X = B\n\t * \n\t * @param B\n\t *            right hand side\n\t * @return solution if A is square, least squares solution otherwise\n\t */\n\n\tpublic Matrix solve(Matrix B)\n\t{\n\t    // assumed m == n\n\t    return new LUDecomposition(this).solve(B);\n\t}\n\n\t/**\n\t * Solve X*A = B, which is also A'*X' = B'\n\t * \n\t * @param B\n\t *            right hand side\n\t * @return solution if A is square, least squares solution otherwise.\n\t */\n\n\tpublic Matrix solveTranspose(Matrix B)\n\t{\n\t    return transpose().solve(B.transpose());\n\t}\n\n\t/**\n\t * Matrix inverse or pseudoinverse\n\t * \n\t * @return inverse(A) if A is square, pseudoinverse otherwise.\n\t */\n\n\tpublic Matrix inverse()\n\t{\n\t    return solve(identity(m, m));\n\t}\n\n\t/**\n\t * Matrix determinant\n\t * \n\t * @return determinant\n\t */\n\n\tpublic double det()\n\t{\n\t    return new LUDecomposition(this).det();\n\t}\n\n\t/**\n\t * Matrix rank\n\t * \n\t * @return effective numerical rank, obtained from SVD.\n\t */\n\n\t// public int rank () {\n\t// return new SingularValueDecomposition(this).rank();\n\t// }\n\t//\n\t// /** Matrix condition (2 norm)\n\t// @return ratio of largest to smallest singular value.\n\t// */\n\t//\n\t// public double cond () {\n\t// return new SingularValueDecomposition(this).cond();\n\t// }\n\t/**\n\t * Matrix trace.\n\t * \n\t * @return sum of the diagonal elements.\n\t */\n\n\tpublic double trace()\n\t{\n\t    double t = 0;\n\t    for (int i = 0; i < Math.Min(m, n); i++)\n\t    {\n\t\tt += A[i][i];\n\t    }\n\t    return t;\n\t}\n\n\t/**\n\t * Generate matrix with random elements\n\t * \n\t * @param m\n\t *            Number of rows.\n\t * @param n\n\t *            Number of colums.\n\t * @return An m-by-n matrix with uniformly distributed random elements.\n\t */\n\n\tpublic static Matrix random(int m, int n)\n\t{\n\t    Matrix A = new Matrix(m, n);\n\t    Random r = new Random();\n\t    double[][] X = A.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    X[i][j] = r.NextDouble();\n\t\t}\n\t    }\n\t    return A;\n\t}\n\n\t/**\n\t * Generate identity matrix\n\t * \n\t * @param m\n\t *            Number of rows.\n\t * @param n\n\t *            Number of colums.\n\t * @return An m-by-n matrix with ones on the diagonal and zeros elsewhere.\n\t */\n\n\tpublic static Matrix identity(int m, int n)\n\t{\n\t    Matrix A = new Matrix(m, n);\n\t    double[][] X = A.getArray();\n\t    for (int i = 0; i < m; i++)\n\t    {\n\t\tfor (int j = 0; j < n; j++)\n\t\t{\n\t\t    X[i][j] = (i == j ? 1.0 : 0.0);\n\t\t}\n\t    }\n\t    return A;\n\t}\n\n\tpublic String toString()\n\t{\n\t    StringBuilder buf = new StringBuilder();\n\t    for (int i = 0; i < getRowDimension(); i++)\n\t    {\n\n\t\tfor (int j = 0; j < getColumnDimension(); j++)\n\t\t{\n\t\t    buf.Append(get(i, j));\n\t\t    buf.Append(\" \");\n\t\t}\n\t\tbuf.Append(\"\\n\");\n\t    }\n\n\t    return buf.ToString();\n\t}\n\n\t/*\n\t * ------------------------ Private Methods ------------------------\n\t */\n\n\t/** Check if size(A) == size(B) * */\n\n\tprivate void checkMatrixDimensions(Matrix B)\n\t{\n\t    if (B.m != m || B.n != n)\n\t    {\n\t\tthrow new ArgumentException(\"Matrix dimensions must agree.\");\n\t    }\n\t}\n    }\n}\n"
  },
  {
    "path": "aima-csharp/util/MixedRadixNumber.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * For details on <a\n     * href=\"http://demonstrations.wolfram.com/MixedRadixNumberRepresentations/\"\n     * >Mixed Radix Number Representations.</a>\n     * \n     * @author Ciaran O'Reilly\n     * @author Mike Stampone\n     */\n    public class MixedRadixNumber\n    {\n\t//\n\tprivate static readonly long serialVersionUID = 1L;\n\t//\n\tprivate long value = 0L;\n\tprivate long maxValue = 0L;\n\tprivate int[] radices = null;\n\tprivate int[] currentNumeralValue = null;\n\tprivate bool recalculate = true;\n\n\t/**\n\t * Constructs a mixed radix number with a specified value and a specified\n\t * array of radices.\n\t * \n\t * @param value\n\t *            the value of the mixed radix number\n\t * @param radices\n\t *            the radices used to represent the value of the mixed radix\n\t *            number\n\t */\n\tpublic MixedRadixNumber(long value, int[] radices)\n\t{\n\t    this.value = value;\n\t    this.radices = new int[radices.Length];\n\t    Array.Copy(radices, 0, this.radices, 0, radices.Length);\n\t    calculateMaxValue();\n\t}\n\n\t/**\n\t * Constructs a mixed radix number with a specified value and a specified\n\t * list of radices.\n\t * \n\t * @param value\n\t *            the value of the mixed radix number\n\t * @param radices\n\t *            the radices used to represent the value of the mixed radix\n\t *            number\n\t */\n\tpublic MixedRadixNumber(long value, List<int> radices)\n\t{\n\t    this.value = value;\n\t    this.radices = new int[radices.Capacity];\n\t    for(int i = 0; i < radices.Capacity; i++)\n\t    {\n\t\tthis.radices[i] = radices[i];\n\t    }\n\t    calculateMaxValue();\n\t}\n\n\t/**\n\t * Constructs a mixed radix number with a specified array of numerals and a\n\t * specified array of radices.\n\t * \n\t * @param radixValues\n\t *            the numerals of the mixed radix number\n\t * @param radices\n\t *            the radices of the mixed radix number\n\t */\n\tpublic MixedRadixNumber(int[] radixValues, int[] radices): this(0, radices)\n\t{\n\t    setCurrentValueFor(radixValues);\n\t}\n\n\t/**\n\t * Returns the value of the mixed radix number with the specified array of\n\t * numerals and the current array of radices.\n\t * \n\t * @return the value of the mixed radix number\n\t * \n\t * @throws IllegalArgumentException\n\t *             if any of the specified numerals is less than zero, or if any\n\t *             of the specified numerals is greater than it's corresponding\n\t *             radix.\n\t */\n\tpublic long getCurrentValueFor(int[] radixValues)\n\t{\n\t    if(radixValues.Length != radices.Length)\n\t    {\n\t\tthrow new ArgumentException(\"Radix values not same size as Radices\");\n\t    }\n\n\t    long cvalue = 0;\n\t    long mvalue = 1;\n\t    for (int i = 0; i < radixValues.Length; i++)\n\t    {\n\t\tif (radixValues[i] < 0 || radixValues[i] >= radices[i])\n\t\t{\n\t\t    throw new ArgumentException(\"Radix value \" + i \n\t\t\t\t\t\t+ \" is out of range for radix at this position\");\n\t\t}\n\t\tif (i > 0)\n\t\t{\n\t\t    mvalue *= radices[i - 1];\n\t\t}\n\t\tcvalue += mvalue * radixValues[i];\n\t    }\n\t    return cvalue;\n\t}\n\n\t/**\n\t * Sets the value of the mixed radix number with the specified array of\n\t * numerals and the current array of radices.\n\t * \n\t * @param radixValues\n\t *            the numerals of the mixed radix number\n\t */\n\tpublic void setCurrentValueFor(int[] radixValues)\n\t{\n\t    this.value = getCurrentValueFor(radixValues);\n\t    Array.Copy(radixValues, 0, this.currentNumeralValue, 0,\n\t\t\t\tradixValues.Length);\n\t    recalculate = false;\n\t}\n\n\t/**\n\t * Returns the maximum value which can be represented by the current array\n\t * of radices.\n\t * \n\t * @return the maximum value which can be represented by the current array\n\t *         of radices.\n\t */\n\tpublic long getMaxAllowedValue()\n\t{\n\t    return maxValue;\n\t}\n\n\t/**\n\t * Increments the value of the mixed radix number, if the value is less than\n\t * the maximum value which can be represented by the current array of\n\t * radices.\n\t * \n\t * @return <code>true</code> if the increment was successful.\n\t */\n\tpublic bool increment()\n\t{\n\t    if (value < maxValue)\n\t    {\n\t\tvalue++;\n\t\trecalculate = true;\n\t\treturn true;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * Decrements the value of the mixed radix number, if the value is greater\n\t * than zero.\n\t * \n\t * @return <code>true</code> if the decrement was successful.\n\t */\n\tpublic bool decrement()\n\t{\n\t    if (value > 0)\n\t    {\n\t\tvalue--;\n\t\trecalculate = true;\n\t\treturn true;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * Returns the numeral at the specified position.\n\t * \n\t * @param atPosition\n\t *            the position of the numeral to return\n\t * @return the numeral at the specified position.\n\t */\n\tpublic int getCurrentNumeralValue(int atPosition)\n\t{\n\t    if (atPosition >= 0 && atPosition < radices.Length)\n\t    {\n\t\tif (recalculate)\n\t\t{\n\t\t    long quotient = value;\n\t\t    for (int i = 0; i < radices.Length; i++)\n\t\t    {\n\t\t\tif (0 != quotient)\n\t\t\t{\n\t\t\t    currentNumeralValue[i] = (int)quotient % radices[i];\n\t\t\t    quotient = quotient / radices[i];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t    currentNumeralValue[i] = 0;\n\t\t\t}\n\t\t    }\n\t\t    recalculate = false;\n\t\t}\n\t\treturn currentNumeralValue[atPosition];\n\t    }\n\t    throw new ArgumentException(\n\t\t\t    \"Argument atPosition must be >=0 and < \" + radices.Length);\n\t}\n\n\t// START_Number\n\n\tpublic int intValue()\n\t{\n\t    return (int)longValue();\n\t}\n\t\n\tpublic long longValue()\n\t{\n\t    return value;\n\t}\n\t\n\tpublic float floatValue()\n\t{\n\t    return longValue();\n\t}\n\t\n\tpublic double doubleValue()\n\t{\n\t    return longValue();\n\t}\n\n\t// END-Number\n\n\tpublic String toString()\n\t{\n\t    System.Text.StringBuilder sb = new System.Text.StringBuilder();\n\n\t    for (int i = 0; i < radices.Length; i++)\n\t    {\n\t\tsb.Append(\"[\");\n\t\tsb.Append(this.getCurrentNumeralValue(i));\n\t\tsb.Append(\"]\");\n\t    }\n\n\t    return sb.ToString();\n\t}\n\n\t// PRIVATE\n\n\t/**\n\t * Sets the maximum value which can be represented by the current array of\n\t * radices.\n\t * \n\t * @throws IllegalArgumentException\n\t *             if no radices are defined, if any radix is less than two, or\n\t *             if the current value is greater than the maximum value which\n\t *             can be represented by the current array of radices.\n\t */\n\tprivate void calculateMaxValue()\n\t{\n\t    if (0 == radices.Length)\n\t    {\n\t\tthrow new ArgumentException(\n\t\t\t\t\"At least 1 radix must be defined.\");\n\t    }\n\t    for (int i = 0; i < radices.Length; i++)\n\t    {\n\t\tif (radices[i] < 2)\n\t\t{\n\t\t    throw new ArgumentException(\n\t\t\t\t    \"Invalid radix, must be >= 2\");\n\t\t}\n\t    }\n\n\t    // Calculate the maxValue allowed\n\t    maxValue = radices[0];\n\t    for (int i = 1; i < radices.Length; i++)\n\t    {\n\t\tmaxValue *= radices[i];\n\t    }\n\t    maxValue -= 1;\n\n\t    if (value > maxValue)\n\t    {\n\t\tthrow new ArgumentException(\n\t\t\t\t\"The value [\"\n\t\t\t\t\t\t+ value\n\t\t\t\t\t\t+ \"] cannot be represented with the radices provided, max value is \"\n\t\t\t\t\t\t+ maxValue);\n\t    }\n\n\t    currentNumeralValue = new int[radices.Length];\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/util/MockRandomizer.cs",
    "content": "using System;\n\nnamespace aima.core.util\n{\n    /**\n     * Mock implementation of the Randomizer interface so that the set of Random\n     * numbers returned are in fact predefined.\n     * \n     * @author Ravi Mohan\n     * \n     */\n    public class MockRandomizer : Randomizer\n    {\n\tprivate double[] values;\n\tprivate int index;\n\n\t/**\n\t * \n\t * @param values\n\t *            the set of predetermined random values to loop over.\n\t */\n\tpublic MockRandomizer(double[] values)\n\t{\n\t    this.values = new double[values.Length];\n\t    System.Array.Copy(values, 0, this.values, 0, values.Length);\n\t    this.index = 0;\n\t}\n\n\t// START-Randomizer\n\tpublic double nextDouble()\n\t{\n\t    if(index == values.Length)\n\t    {\n\t\tindex = 0;\n\t    }\n\t    return values[index++];\n\t}\n\n\t//END-Randomizer\n    }\n}"
  },
  {
    "path": "aima-csharp/util/Pair.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * @author Ravi Mohan\n     * @author Mike Stampone\n     * \n     */\n    public class Pair<X, Y>\n    {\n        private X a;\n\n        private Y b;\n\n        /**\n    \t * Constructs a Pair from two given elements\n    \t * \n    \t * @param a\n    \t *            the first element\n    \t * @param b\n    \t *            the second element\n    \t */\n        public Pair(X a, Y b)\n        {\n            this.a = a;\n            this.b = b;\n        }\n\n        /**\n\t * Returns the first element of the pair\n    \t * \n    \t * @return the first element of the pair\n    \t */\n        public X getFirst()\n        {\n            return a;\n        }\n\n        /**\n         * Returns the second element of the pair\n\t * \n\t * @return the second element of the pair\n\t */\n        public Y getSecond()\n        {\n            return b;\n        }\n\n\n        public override bool Equals(Object o)\n        {\n            if (o is Pair<X, Y>)\n            {\n                Pair<X, Y> p = (Pair<X, Y>)o;\n                return a.Equals(p.a) && b.Equals(p.b);\n            }\n            return false;\n        }\n\n        public int hashCode()\n        {\n            return a.GetHashCode() + 31 * b.GetHashCode();\n        }\n\n        public override String ToString()\n        {\n            return \"< \" + getFirst().ToString() + \" , \" + getSecond().ToString()\n                    + \" > \";\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/util/Point2D.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * Simplified version of <code>java.awt.geom.Point2D</code>. We do not want\n     * dependencies to presentation layer packages here.\n     * \n     * @author R. Lunde\n     * @author Mike Stampone\n     */\n    public class Point2D\n    {\n        private double x;\n        private double y;\n\n        public Point2D(double x, double y)\n        {\n            this.x = x;\n            this.y = y;\n        }\n\n        /**\n    \t * Returns the X coordinate of this <code>Point2D</code> in\n    \t * <code>double</code> precision.\n    \t * \n    \t * @return the X coordinate of this <code>Point2D</code>.\n    \t */\n        public double getX()\n        {\n            return x;\n        }\n\n        /**\n    \t * Returns the Y coordinate of this <code>Point2D</code> in\n    \t * <code>double</code> precision.\n      \t * \n    \t * @return the Y coordinate of this <code>Point2D</code>.\n\t     */\n        public double getY()\n        {\n            return y;\n        }\n\n        /**\n    \t * Returns the Euclidean distance between a specified point and this point.\n    \t * \n    \t * @return the Euclidean distance between a specified point and this point.\n\t     */\n        public double distance(Point2D pt)\n        {\n            // Distance Between X Coordinates\n            double x_distance = (pt.getX() - x) * (pt.getX() - x);\n            // Distance Between Y Coordinates\n            double y_distance = (pt.getY() - y) * (pt.getY() - y);\n            // Distance Between 2d Points\n            double total_distance = Math.Sqrt(x_distance + y_distance);\n\n            return total_distance;\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/util/Randomizer.cs",
    "content": "namespace aima.core.util\n{\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public interface Randomizer\n    {\n\t/**\n\t * \n\t * @return a double value, chosen (approximately) uniformly from the range\n\t *         [0.0d, 1.0d), i.e. 0.0d (inclusive) to 1.0d (exclusive).\n\t */\n\tdouble nextDouble();\n    }\n}"
  },
  {
    "path": "aima-csharp/util/SetOps.cs",
    "content": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace aima.core.util\n{\n    /**\n     * Note: This code is based on - <a href=\n     * \"http://download.oracle.com/javase/tutorial/collections/interfaces/set.html\"\n     * >Java Tutorial: The Set Interface</a> <br>\n     * \n     * Using LinkedHashSet, even though slightly slower than HashSet, in order to\n     * ensure order is always respected (i.e. if called with TreeSet or\n     * LinkedHashSet implementations).\n     * \n     * @author Ciaran O'Reilly\n     * @author Ravi Mohan\n     */\n    public class SetOps\n    {\n        /**\n    \t * \n    \t * @param <T>\n    \t * @param s1\n    \t * @param s2\n    \t * @return the union of s1 and s2. (The union of two sets is the set\n    \t *         containing all of the elements contained in either set.)\n    \t */\n        public static List<T> union<T>(List<T> s1, List<T> s2)\n        {\n            if(s1 == s2)\n            {\n                return s1;\n            }\n            LinkedHashSet<T> union = new LinkedHashSet<T>(s1);\n            union.UnionWith(s2);\n            return union.ToList<T>();\n        }\n\n        /**\n         * \n         * @param <T>\n    \t * @param s1\n    \t * @param s2\n    \t * @return the intersection of s1 and s2. (The intersection of two sets is\n    \t *         the set containing only the elements common to both sets.)\n    \t */\n        public static List<T> intersection<T>(List<T> s1, List<T> s2)\n        {\n            if (s1 == s2)\n            {\n                return s1;\n            }\n            LinkedHashSet<T> intersection = new LinkedHashSet<T>(s1);\n            intersection.IntersectWith(s2);\n            return intersection.ToList<T>();\n        }\n\n        /**\n     \t * \n    \t * @param <T>\n    \t * @param s1\n    \t * @param s2\n    \t * @return the (asymmetric) set difference of s1 and s2. (For example, the\n    \t *         set difference of s1 minus s2 is the set containing all of the\n    \t *         elements found in s1 but not in s2.)\n    \t */\n        public static List<T> difference<T>(List<T> s1, List<T> s2)\n        {\n            LinkedHashSet<T> difference = new LinkedHashSet<T>(s1);\n            difference.ExceptWith(s2);\n            return difference.ToList<T>();\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/util/Table.cs",
    "content": "using System.Collections.Generic;\nusing System.Text;\n\nnamespace aima.core.util\n{\n    /**\n     * @author Ravi Mohan\n     * @author Mike Stampone\n     * \n     */\n    public class Table<RowHeaderType, ColumnHeaderType, ValueType> // where ValueType : struct\n    {\n        private List<RowHeaderType> rowHeaders;\n        private List<ColumnHeaderType> columnHeaders;\n        private Dictionary<RowHeaderType, Dictionary<ColumnHeaderType, ValueType>> rows;\n\n        public Table(List<RowHeaderType> rowHeaders,\n                List<ColumnHeaderType> columnHeaders)\n        {\n\n            this.rowHeaders = rowHeaders;\n            this.columnHeaders = columnHeaders;\n            this.rows = new Dictionary<RowHeaderType, Dictionary<ColumnHeaderType, ValueType>>();\n            foreach (RowHeaderType rowHeader in rowHeaders)\n            {\n                rows.Add(rowHeader, new Dictionary<ColumnHeaderType, ValueType>());\n            }\n        }\n\n        public void set(RowHeaderType r, ColumnHeaderType c, ValueType v)\n        {\n            if (rows[r].ContainsKey(c))\n            {\n                rows[r][c] = v;\n            }\n            else\n            {\n                rows[r].Add(c, v);\n            }\n        }\n\n        public ValueType get(RowHeaderType r, ColumnHeaderType c)\n        {\n            if (!rows.ContainsKey(r))\n            {\n                return default(ValueType);\n            }\n            Dictionary<ColumnHeaderType, ValueType> rowValues = rows[r];\n\n            if (rowValues == null || !rowValues.ContainsKey(c))\n            {\n                return default(ValueType);\n            }\n            return rowValues[c];\n        }\n\n        public override System.String ToString()\n        {\n            StringBuilder buf = new StringBuilder();\n            foreach (RowHeaderType r in rowHeaders)\n            {\n                foreach (ColumnHeaderType c in columnHeaders)\n                {\n                    buf.Append(get(r, c).ToString());\n                    buf.Append(\" \");\n                }\n                buf.Append(\"\\n\");\n            }\n            return buf.ToString();\n        }\n\n        class Row<R>\n        {\n            private Dictionary<ColumnHeaderType, ValueType> c;\n\n            public Row()\n            {\n\n                this.c = new Dictionary<ColumnHeaderType, ValueType>();\n            }\n\n            public Dictionary<ColumnHeaderType, ValueType> cells()\n            {\n                return this.c;\n            }\n\n        }\n\n        class Cell<ValueHeaderType>\n        {\n            private ValueHeaderType val;\n\n            public Cell()\n            {\n                val = default(ValueHeaderType);\n            }\n\n            public Cell(ValueHeaderType value)\n            {\n                this.val = value;\n            }\n\n            public void set(ValueHeaderType value)\n            {\n                this.val = value;\n            }\n\n            public ValueHeaderType value()\n            {\n                return val;\n            }\n\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/util/Triplet.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * @author Ravi Mohan\n     * @author Mike Stampone\n     * \n     */\n     public class Triplet<X, Y, Z>\n    {\n        private X x;\n\n\tprivate Y y;\n\n        private Z z;\n\n\t/**\n\t * Constructs a triplet with three specified elements.\n\t * \n\t * @param x\n\t *            the first element of the triplet.\n\t * @param y\n\t *            the second element of the triplet.\n\t * @param z\n\t *            the third element of the triplet.\n\t */\n\tpublic Triplet(X x, Y y, Z z)\n        {\n            this.x = x;\n            this.y = y;\n            this.z = z;\n        }\n\n        /**\n\t * Returns the second element of the triplet.\n\t * \n\t * @return the second element of the triplet.\n\t */\n        public Y getSecond()\n        {\n            return y;\n        }\n\n        /**\n\t * Returns the third element of the triplet.\n\t * \n\t * @return the third element of the triplet.\n\t */\n        public Z getThird()\n        {\n            return z;\n        }\n\n        public override bool Equals(Object o)\n        {\n            if (o is Triplet<X, Y, Z>)\n            {\n                Triplet<X, Y, Z> other = (Triplet<X, Y, Z>)o;\n                return (x.Equals(other.x)) && (y.Equals(other.y))\n                        && (y.Equals(other.y));\n            }\n            return false;\n        }\n\n        public int hashCode()\n        {\n            return x.GetHashCode() + 31 * y.GetHashCode() + 31 * z.GetHashCode();\n        }\n\n        public String toString()\n        {\n            return \"< \" + x.ToString() + \" , \" + y.ToString() + \" , \"\n                    + z.ToString() + \" >\";\n        }\n    }\n}"
  },
  {
    "path": "aima-csharp/util/TwoKeyHashMap.cs",
    "content": "using System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * Provides a hash map which is indexed by two keys. In fact this is just a hash\n     * map which is indexed by a pair containing the two keys. The provided two-key\n     * access methods try to increase code readability.\n     * \n     * @param <K1>\n     *            First key\n     * @param <K2>\n     *            Second key\n     * @param <V>\n     *            Result value\n     * \n     * @author Ruediger Lunde\n     * @author Mike Stampone\n     */\n    public class TwoKeyHashMap<K1, K2, V> : Dictionary<Pair<K1, K2>, V>\n    {\n\tprivate static readonly long serialVersionUID = -2232849394229644162L;\n\n\t/**\n\t * Associates the specified value with the specified key pair in this map.\n\t * If the map previously contained a mapping for this key pair, the old\n\t * value is replaced.\n\t * \n\t * @param key1\n\t *            the first key of the key pair, with which the specified value\n\t *            is to be associated.\n\t * @param key2\n\t *            the second key of the key pair, with which the specified value\n\t *            is to be associated.\n\t * @param value\n\t *            the value to be associated with the key pair.\n\t * \n\t */\n\tpublic void put(K1 key1, K2 key2, V value)\n\t{\n\t    base.Add(new Pair<K1, K2>(key1, key2), value);\n\t}\n\n\t/**\n\t * Returns the value to which the specified key pair is mapped in this two\n\t * key hash map, or <code>null</code> if the map contains no mapping for\n\t * this key pair. A return value of null does not <em>necessarily</em>\n\t * indicate that the map contains no mapping for the key; it is also\n\t * possible that the map explicitly maps the key to <code>null</code>. The\n\t * <code>containsKey</code> method may be used to distinguish these two\n\t * cases.\n\t * \n\t * @param key1\n\t *            the first key of the key pair, whose associated value is to be\n\t *            returned.\n\t * @param key2\n\t *            the second key of the key pair, whose associated value is to\n\t *            be returned.\n\t * \n\t * @return the value to which this map maps the specified key pair, or\n\t *         <code>null</code> if the map contains no mapping for this key\n\t *         pair.\n\t */\n\tpublic V get(K1 key1, K2 key2)\n\t{\n\t    V value;\n\t    if(base.TryGetValue(new Pair<K1, K2>(key1, key2), out value))\n\t    {\n\t\treturn value;\n\t    }\n\n\t    return value;\n\t}\n\n\t/**\n\t * Returns <code>true</code> if this map contains a mapping for the\n\t * specified key pair.\n\t * \n\t * @param key1\n\t *            the first key of the key pair whose presence in this map is to\n\t *            be tested.\n\t * @param key2\n\t *            the second key of the key pair whose presence in this map is\n\t *            to be tested.\n\t * \n\t * @return <code>true</code> if this map contains a mapping for the\n\t *         specified key.\n\t */\n\tpublic bool containsKey(K1 key1, K2 key2)\n\t{\n\t    return base.ContainsKey(new Pair<K1, K2>(key1, key2));\n\t}\n\n\t/**\n\t * Removes the mapping for this key pair from this map if present.\n\t * \n\t * @param key1\n\t *            the first key of the key pair, whose mapping is to be removed\n\t *            from the map.\n\t * @param key2\n\t *            the second key of the key pair, whose mapping is to be removed\n\t *            from the map.\n\t * \n\t * @return the previous value associated with the specified key pair, or\n\t *         <code>null</code> if there was no mapping for the key pair. A\n\t *         <code>null</code> return can also indicate that the map\n\t *         previously associated <code>null</code> with the specified key\n\t *         pair.\n\t */\n\tpublic V removeKey(K1 key1, K2 key2, V value)\n\t{\n\t    base.Remove(new Pair<K1, K2>(key1, key2));\n\t    return value;\n\t}\n\n\t// public static void main(String[] args) {\n\t// TwoKeyHashMap<String, String, String> hash = new TwoKeyHashMap<String,\n\t// String, String>();\n\t// hash.put(\"A\", \"A\", \"C\");\n\t// hash.put(\"A\", \"A\", \"D\");\n\t// hash.put(\"B\", \"A\", \"E\");\n\t// System.Console.WriteLine(hash.get(\"A\", \"A\"));\n\t// System.Console.WriteLine(hash.get(\"A\", \"B\"));\n\t// }\t\n    }\n}"
  },
  {
    "path": "aima-csharp/util/Util.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nnamespace aima.core.util\n{\n\n    /**\n     * @author Ravi Mohan\n     * \n     */\n    public class Util\n    {\n        public const String NO = \"No\";\n\n        public const String YES = \"Yes\";\n        \n        private static Random r = new Random();\n\n        /**\n\t * Get the first element from a list.\n\t * \n    \t * @param l\n    \t *            the list the first element is to be extracted from.\n    \t * @return the first element of the passed in list.\n    \t */\n        public static T first<T>(List<T> l)\n        {\n            return l[0];\n        }\n\n        /**\n    \t * Get a sublist of all of the elements in the list except for first.\n    \t * \n    \t * @param l\n    \t *            the list the rest of the elements are to be extracted from.\n    \t * @return a list of all of the elements in the passed in list except for\n    \t *         the first element.\n    \t */\n        public static List<T> rest<T>(List<T> l)\n        {\n            List<T> newList = l.GetRange(1, l.Count - 1);\n            return newList;\n        }\n\n        /**\n\t    * Create a set for the provided values.\n\t    * @param values\n\t    *        the sets initial values.\n\t    * @return a Set of the provided values.\n\t    */\n    \n        public static HashSet<T> createSet<T>(params T[] values)\n        {\n            HashSet<T> set = new HashSet<T>();\n\n            foreach(T t in values)\n            {\n                set.Add(t);\n            }\n\n            return set;\n        }\n\n\n        public static bool randombool()\n        {\n            int trueOrFalse = r.Next(2);\n            return (!(trueOrFalse == 0));\n        }\n\n        /**\n    \t * Randomly select an element from a list.\n    \t * \n    \t * @param <T>\n    \t *            the type of element to be returned from the list l.\n    \t * @param l\n    \t *            a list of type T from which an element is to be selected\n    \t *            randomly.\n    \t * @return a randomly selected element from l.\n\t     */\n        public static T selectRandomlyFromList<T>(List<T> l)\n        {\n            return l[r.Next(l.Count)];\n        }\n\n\n        public static double[] normalize(double[] probDist)\n        {\n            int len = probDist.Length;\n            double total = 0.0;\n            foreach (double d in probDist)\n            {\n                total = total + d;\n            }\n\n            double[] normalized = new double[len];\n            if (total != 0)\n            {\n                for (int i = 0; i < len; i++)\n                {\n                    normalized[i] = probDist[i] / total;\n                }\n            }\n            return normalized;\n        }\n\n        public static List<Double> normalize(List<Double> values)\n        {\n            double[] valuesAsArray = new double[values.Count];\n            for (int i = 0; i < valuesAsArray.Length; i++)\n            {\n                valuesAsArray[i] = values[i];\n            }\n            double[] normalized = normalize(valuesAsArray);\n            List<Double> results = new List<Double>();\n            for (int i = 0; i < normalized.Length; i++)\n            {\n                results.Add(normalized[i]);\n            }\n            return results;\n        }\n\n        public static int min(int i, int j)\n        {\n            return (i > j ? j : i);\n        }\n\n        public static int max(int i, int j)\n        {\n            return (i < j ? j : i);\n        }\n\n        public static int max(int i, int j, int k)\n        {\n            return max(max(i, j), k);\n        }\n\n        public static int min(int i, int j, int k)\n        {\n            return min(min(i, j), k);\n        }\n\n        public static T mode<T>(List<T> l)\n        {\n            Dictionary<T, int> hash = new Dictionary<T, int>();\n            foreach (T obj in l)\n            {\n                if (hash.ContainsKey(obj))\n                {\n                    hash[obj] = hash[obj] + 1;\n                }\n                else\n                {\n                    hash.Add(obj, 1);\n                }\n            }\n\n            T maxkey = hash.Keys.FirstOrDefault<T>();\n            foreach (T key in hash.Keys)\n            {\n                if (hash[key] > hash[maxkey])\n                {\n                    maxkey = key;\n                }\n            }\n            return maxkey;\n        }\n\n        public static String[] yesno()\n        {\n            return new String[] { YES, NO };\n        }\n\n        public static double log2(double d)\n        {\n            return System.Math.Log(d) / System.Math.Log(2);\n        }\n\n        public static double information(double[] probabilities)\n        {\n            double total = 0.0;\n            foreach (double d in probabilities)\n            {\n                total += (-1.0 * log2(d) * d);\n            }\n            return total;\n        }\n\n        public static List<T> removeFrom<T>(List<T> list, T member)\n        {\n            List<T> newList = new List<T>(list);\n            newList.Remove(member);\n            return newList;\n        }\n\n        public static double sumOfSquares<T>(List<T> list)\n        {\n            double accum = 0;\n            foreach (T item in list)\n            {\n                accum = accum + (Convert.ToDouble(item) * Convert.ToDouble(item));\n            }\n            return accum;\n        }\n\n        public static String ntimes(String s, int n)\n        {\n            StringBuilder buf = new StringBuilder();\n            for (int i = 0; i < n; i++)\n            {\n                buf.Append(s);\n            }\n            return buf.ToString();\n        }\n\n        public static void checkForNanOrInfinity(double d)\n        {\n            if (Double.IsNaN(d))\n            {\n                throw new ArgumentException(\"Not a Number\");\n            }\n            if (Double.IsInfinity(d))\n            {\n                throw new ArgumentException(\"Infinite Number\");\n            }\n        }\n\n        public static int randomNumberBetween(int i, int j)\n        {\n            /* i,j bothinclusive */\n            return r.Next(j - i + 1) + i;\n        }\n\n        public static double calculateMean(List<Double> lst)\n        {\n            Double sum = 0.0;\n            foreach (Double d in lst)\n            {\n                sum = sum + d;\n            }\n            return sum / lst.Count;\n        }\n\n        public static double calculateStDev(List<Double> values, double mean)\n        {\n\n            int listSize = values.Count;\n\n            Double sumOfDiffSquared = 0.0;\n            foreach (Double value in values)\n            {\n                double diffFromMean = value - mean;\n                sumOfDiffSquared += ((diffFromMean * diffFromMean) / (listSize - 1));\n                // division moved here to avoid sum becoming too big if this\n                // doesn't work use incremental formulation\n\n            }\n            double variance = sumOfDiffSquared;\n            // (listSize - 1);\n            // assumes at least 2 members in list.\n            return System.Math.Sqrt(variance);\n        }\n\n        public static List<Double> normalizeFromMeanAndStdev(List<Double> values,\n                double mean, double stdev)\n        {\n            List<Double> normalized = new List<Double>();\n            foreach (Double d in values)\n            {\n                normalized.Add((d - mean) / stdev);\n            }\n            return normalized;\n        }\n\n        public static double generateRandomDoubleBetween(double lowerLimit,\n                double upperLimit)\n        {\n\n            return lowerLimit + ((upperLimit - lowerLimit) * r.NextDouble());\n        }\n    }\n}\n"
  },
  {
    "path": "aima-csharp/util/Vector.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * @author Ravi Mohan\n     * @author Mike Stampone\n     */\n    public class Vector : Matrix\n    {\n\tprivate static readonly long serialVersionUID = 1L;\n\n\t// Vector is modelled as a matrix with a single column;\n\t/**\n\t * Constructs a vector with the specified size.\n\t * \n\t * @param size\n\t *            the capacity of the vector\n\t */\n\tpublic Vector(int size) : base(size, 1)\n\t{\n\n\t}\n\n\t/**\n\t * Constructs a vector with the specified list of values.\n\t * \n\t * @param lst\n\t *            a list of values\n\t */\n\tpublic Vector(List<double> lst) : base(lst.Count, 1)\n\t{\n\t    for (int i = 0; i < lst.Count; i++)\n\t    {\n\t\tsetValue(i, lst[i]);\n\t    }\n\t}\n\n\t/**\n\t * Returns the value at the specified index.\n\t * \n\t * @param i\n\t *            the index of the value to return.\n\t * \n\t * @return the value at the specified index.\n\t */\n\tpublic double getValue(int i)\n\t{\n\t    return base.get(i, 0);\n\t}\n\n\t/**\n\t * Sets the value at the specified index.\n\t * \n\t * @param index\n\t *            the index of the value to set.\n\t * @param value\n\t *            the value to be placed at the index.\n\t */\n\tpublic void setValue(int index, double value)\n\t{\n\t    base.set(index, 0, value);\n\t}\n\n\t/**\n\t * Returns a copy of this vector.\n\t * \n\t * @return a copy of this vector.\n\t */\n\tpublic Vector copyVector()\n\t{\n\t    Vector result = new Vector(getRowDimension());\n\t    for (int i = 0; i < getRowDimension(); i++)\n\t    {\n\t\tresult.setValue(i, getValue(i));\n\t    }\n\t    return result;\n\t}\n\n\t/**\n\t * Returns the number of values in this vector.\n\t * \n\t * @return the number of values in this vector.\n\t */\n\tpublic int size()\n\t{\n\t    return getRowDimension();\n\t}\n\n\t/**\n\t * Returns the result of vector subtraction.\n\t * \n\t * @param v\n\t *            the vector to subtract\n\t * \n\t * @return the result of vector subtraction.\n\t */\n\tpublic Vector minus(Vector v)\n\t{\n\t    Vector result = new Vector(size());\n\t    for (int i = 0; i < size(); i++)\n\t    {\n\t\tresult.setValue(i, getValue(i) - v.getValue(i));\n\t    }\n\t    return result;\n\t}\n\n\n\t/**\n\t * Returns the result of vector addition.\n\t * \n\t * @param v\n\t *            the vector to add\n\t * \n\t * @return the result of vector addition.\n\t */\n\tpublic Vector plus(Vector v)\n\t{\n\t    Vector result = new Vector(size());\n\t    for (int i = 0; i < size(); i++)\n\t    {\n\t\tresult.setValue(i, getValue(i) + v.getValue(i));\n\t    }\n\t    return result;\n\t}\n\n\t/**\n\t * Returns the index at which the maximum value in this vector is located.\n\t * \n\t * @return the index at which the maximum value in this vector is located.\n\t * \n\t * @throws RuntimeException\n\t *             if the vector does not contain any values.\n\t */\n\tpublic int indexHavingMaxValue()\n\t{\n\t    if (size() <= 0)\n\t    {\n\t\tthrow new InvalidOperationException(\"can't perform this op on empty vector\");\n\t    }\n\t    int res = 0;\n\t    for (int i = 0; i < size(); i++)\n\t    {\n\t\tif (getValue(i) > getValue(res))\n\t\t{\n\t\t    res = i;\n\t\t}\n\t    }\n\t    return res;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp/util/XYLocation.cs",
    "content": "using System;\nusing System.Collections.Generic;\n\nnamespace aima.core.util\n{\n    /**\n     * Note: If looking at a rectangle - the coordinate (x=0, y=0) will be the top\n     * left hand corner. This corresponds with Java's AWT coordinate system.\n     * \n     * @author Ravi Mohan\n     * @author Mike Stampone\n     */\n    public class XYLocation\n    {\n\tpublic enum Direction\n\t{\n\t    North, South, East, West\n\t};\n\n\tint xCoOrdinate, yCoOrdinate;\n\n\t/**\n\t * Constructs and initializes a location at the specified (<em>x</em>,\n\t * <em>y</em>) location in the coordinate space.\n\t * \n\t * @param x\n\t *            the x coordinate\n\t * @param y\n\t *            the y coordinate\n\t */\n\tpublic XYLocation(int x, int y)\n\t{\n\t    xCoOrdinate = x;\n\t    yCoOrdinate = y;\n\t}\n\n\t/**\n\t * Returns the X coordinate of the location in integer precision.\n\t * \n\t * @return the X coordinate of the location in double precision.\n\t */\n\tpublic int getXCoOrdinate()\n\t{\n\t    return xCoOrdinate;\n\t}\n\n\tpublic int getYCoOrdinate()\n\t{\n\t    return yCoOrdinate;\n\t}\n\n\t/**\n\t * Returns the location one unit left of this location.\n\t * \n\t * @return the location one unit left of this location.\n\t */\n\tpublic XYLocation west()\n\t{\n\t    return new XYLocation(xCoOrdinate - 1, yCoOrdinate);\n\t}\n\n\t/**\n\t * Returns the location one unit right of this location.\n\t * \n\t * @return the location one unit right of this location.\n\t */\n\tpublic XYLocation east()\n\t{\n\t    return new XYLocation(xCoOrdinate + 1, yCoOrdinate);\n\t}\n\n\t/**\n\t * Returns the location one unit ahead of this location.\n\t * \n\t * @return the location one unit ahead of this location.\n\t */\n\tpublic XYLocation north()\n\t{\n\t    return new XYLocation(xCoOrdinate, yCoOrdinate - 1);\n\t}\n\n\t/**\n\t * Returns the location one unit behind, this location.\n\t * \n\t * @return the location one unit behind this location.\n\t */\n\tpublic XYLocation south()\n\t{\n\t    return new XYLocation(xCoOrdinate, yCoOrdinate + 1);\n\t}\n\n\t/**\n\t * Returns the location one unit left of this location.\n\t * \n\t * @return the location one unit left of this location.\n\t */\n\tpublic XYLocation left()\n\t{\n\t    return west();\n\t}\n\n\t/**\n\t * Returns the location one unit right of this location.\n\t * \n\t * @return the location one unit right of this location.\n\t */\n\tpublic XYLocation right()\n\t{\n\t    return east();\n\t}\n\n\t/**\n\t * Returns the location one unit above this location.\n\t * \n\t * @return the location one unit above this location.\n\t */\n\tpublic XYLocation up()\n\t{\n\t    return north();\n\t}\n\n\t/**\n\t * Returns the location one unit below this location.\n\t * \n\t * @return the location one unit below this location.\n\t */\n\tpublic XYLocation down()\n\t{\n\t    return south();\n\t}\n\n\t/**\n\t * Returns the location one unit from this location in the specified\n\t * direction.\n\t * \n\t * @return the location one unit from this location in the specified\n\t *         direction.\n\t */\n\tpublic XYLocation locationAt(Direction direction)\n\t{\n\t    if (direction.Equals(Direction.North))\n\t    {\n\t\treturn north();\n\t    }\n\t    if (direction.Equals(Direction.South))\n\t    {\n\t\treturn south();\n\t    }\n\t    if (direction.Equals(Direction.East))\n\t    {\n\t\treturn east();\n\t    }\n\t    if (direction.Equals(Direction.West))\n\t    {\n\t\treturn west();\n\t    }\n\t    else\n\t    {\n\t\tthrow new SystemException(\"Unknown direction \" + direction);\n\t    }\n\t}\n\n\tpublic bool equals(Object o)\n\t{\n\t    if (null == o || !(o is XYLocation)) {\n\t\treturn base.Equals(o);\n\t    }\n\t    XYLocation anotherLoc = (XYLocation)o;\n\t    return ((anotherLoc.getXCoOrdinate() == xCoOrdinate) && (anotherLoc\n\t\t\t    .getYCoOrdinate() == yCoOrdinate));\n\t}\n\t\n\tpublic String toString()\n\t{\n\t    return \" ( \" + xCoOrdinate + \" , \" + yCoOrdinate + \" ) \";\n\t}\n\t\n\tpublic int hashCode()\n\t{\n\t    int result = 17;\n\t    result = 37 * result + xCoOrdinate;\n\t    result = 43 * result + yCoOrdinate;\n\t    return result;\n\t}\n    }\n}"
  },
  {
    "path": "aima-csharp-unity/.gitignore",
    "content": "/[Ll]ibrary/\n/[Tt]emp/\n/[Oo]bj/\n/[Bb]uild/\n/[Bb]uilds/\n/Assets/AssetStoreTools*\n\n# Autogenerated VS/MD solution and project files\nExportedObj/\n*.csproj\n*.unityproj\n*.sln\n*.suo\n*.tmp\n*.user\n*.userprefs\n*.pidb\n*.booproj\n*.svd\n\n\n# Unity3D generated meta files\n*.pidb.meta\n\n# Unity3D Generated File On Crash Reports\nsysinfo.txt\n\n# Builds\n*.apk\n*.unitypackage"
  },
  {
    "path": "aima-csharp-unity/README.md",
    "content": "# ![](https://github.com/aimacode/aima-java/blob/gh-pages/aima3e/images/aima3e.jpg)aima-csharp-unity\n![Unity](https://madewith.unity.com/profiles/mwu/themes/custom/mwu_theme/logo.png)\nUnity implementation of algorithms from [Russell](http://www.cs.berkeley.edu/~russell/) And [Norvig's](http://www.norvig.com/) [Artificial Intelligence - A Modern Approach 3rd Edition](http://aima.cs.berkeley.edu/). You can use this in conjunction with a course on AI, or for study on your own.\n"
  },
  {
    "path": "aima-csharp.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.25123.0\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"aima-csharp\", \"aima-csharp\\aima-csharp.csproj\", \"{125F53D5-1CCF-4DAF-82FE-4324686CF417}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{125F53D5-1CCF-4DAF-82FE-4324686CF417}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{125F53D5-1CCF-4DAF-82FE-4324686CF417}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{125F53D5-1CCF-4DAF-82FE-4324686CF417}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{125F53D5-1CCF-4DAF-82FE-4324686CF417}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  }
]