stash
This commit is contained in:
		
							parent
							
								
									7c8e17ec59
								
							
						
					
					
						commit
						8e6e9edf64
					
				
					 6 changed files with 215 additions and 0 deletions
				
			
		
							
								
								
									
										22
									
								
								.devcontainer/Dockerfile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								.devcontainer/Dockerfile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | ||||||
|  | FROM sjkillen/clyngor | ||||||
|  | 
 | ||||||
|  | RUN apt-get -qq update; apt-get -qq install sudo | ||||||
|  | 
 | ||||||
|  | ARG USERNAME=asp | ||||||
|  | ARG USER_UID=1000 | ||||||
|  | ARG USER_GID=$USER_UID | ||||||
|  | 
 | ||||||
|  | # Copied from https://code.visualstudio.com/docs/remote/containers-advanced#_adding-a-nonroot-user-to-your-dev-container | ||||||
|  | 
 | ||||||
|  | # Create the user | ||||||
|  | RUN groupadd --gid $USER_GID $USERNAME \ | ||||||
|  |     && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME --shell /bin/bash \ | ||||||
|  |     # | ||||||
|  |     # [Optional] Add sudo support. Omit if you don't need to install software after connecting. | ||||||
|  |     && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ | ||||||
|  |     && chmod 0440 /etc/sudoers.d/$USERNAME | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | USER $USERNAME | ||||||
|  | 
 | ||||||
|  | ENTRYPOINT ["bash"] | ||||||
							
								
								
									
										34
									
								
								.devcontainer/devcontainer.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								.devcontainer/devcontainer.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | // For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at: | ||||||
|  | // https://github.com/microsoft/vscode-dev-containers/tree/v0.117.0/containers/docker-existing-dockerfile | ||||||
|  | { | ||||||
|  | 	"name": "Clyngor setup", | ||||||
|  | 
 | ||||||
|  | 	// Sets the run context to one level up instead of the .devcontainer folder. | ||||||
|  | 	"context": "..", | ||||||
|  | 
 | ||||||
|  | 	// Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename. | ||||||
|  | 	"dockerFile": "./Dockerfile", | ||||||
|  | 
 | ||||||
|  | 	// Set *default* container specific settings.json values on container create. | ||||||
|  | 	"settings": {  | ||||||
|  | 		"terminal.integrated.shell.linux": null | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	// Add the IDs of extensions you want installed when the container is created. | ||||||
|  | 	"extensions": ["abelcour.asp-syntax-highlight", "ms-python.python"] | ||||||
|  | 
 | ||||||
|  | 	// Use 'forwardPorts' to make a list of ports inside the container available locally. | ||||||
|  | 	// "forwardPorts": [], | ||||||
|  | 
 | ||||||
|  | 	// Uncomment the next line to run commands after the container is created - for example installing git. | ||||||
|  | 	// "postCreateCommand": "apt-get update && apt-get install -y git", | ||||||
|  | 
 | ||||||
|  | 	// Uncomment when using a ptrace-based debugger like C++, Go, and Rust | ||||||
|  | 	// "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ], | ||||||
|  | 
 | ||||||
|  | 	// Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-in-docker. | ||||||
|  | 	// "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ], | ||||||
|  | 
 | ||||||
|  | 	// Uncomment to connect as a non-root user. See https://aka.ms/vscode-remote/containers/non-root. | ||||||
|  | 	// "remoteUser": "vscode" | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | notes | ||||||
							
								
								
									
										3
									
								
								.vscode/settings.json
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | { | ||||||
|  |     "discord.enabled": true | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								ontology.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								ontology.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | ||||||
|  | from typing import Set | ||||||
|  | 
 | ||||||
|  | models = ( | ||||||
|  |     {"a", "b", "c"}, | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | DL_ATOMS = set.union(*models) | ||||||
|  | 
 | ||||||
|  | def propagate(atoms: Set[str]) -> Set[str]: | ||||||
|  |     atoms = atoms.intersection(DL_ATOMS) | ||||||
|  |     sub_models = (model for model in models if atoms <= model) | ||||||
|  |     first: set = next(sub_models, None) | ||||||
|  |     if first is None: | ||||||
|  |         return set() | ||||||
|  |     return first.intersection(*sub_models) | ||||||
|  | 
 | ||||||
|  | def check(atoms: Set[str]) -> bool: | ||||||
|  |     atoms = atoms.intersection(DL_ATOMS) | ||||||
|  |     return atoms in models | ||||||
							
								
								
									
										136
									
								
								propagator.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								propagator.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,136 @@ | ||||||
|  | from copy import deepcopy | ||||||
|  | from itertools import chain | ||||||
|  | from operator import itemgetter | ||||||
|  | from typing import Iterable, List, Tuple | ||||||
|  | import clingo | ||||||
|  | from clingo import PropagateControl, PropagateInit, PropagateControl, PropagatorCheckMode, Assignment, Symbol, Control, TheoryAtom | ||||||
|  | 
 | ||||||
|  | import ontology as O | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Ontology: | ||||||
|  |     def init(self, init: PropagateInit) -> None: | ||||||
|  |         init.check_mode = PropagatorCheckMode.Total | ||||||
|  |         | ||||||
|  |         self.assignment = dict() | ||||||
|  | 
 | ||||||
|  |         self.symbolic_atoms = { | ||||||
|  |             init.solver_literal(atom.literal): str(atom.symbol) | ||||||
|  |             for atom in init.symbolic_atoms | ||||||
|  |         } | ||||||
|  |         self.theory_atoms = { | ||||||
|  |             init.solver_literal(atom.literal): atom.elements[0].terms[0].name | ||||||
|  |             for atom in init.theory_atoms | ||||||
|  |         } | ||||||
|  |         self.symbolic_atoms_inv = { v: k for k, v in self.symbolic_atoms.items() } | ||||||
|  |         self.theory_atoms_inv = { v: k for k, v in self.theory_atoms.items() } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         # Might only need to watch just theory atoms / just symbol atoms but for now | ||||||
|  |         # watching everything is easier  | ||||||
|  |         for lit in chain(self.symbolic_atoms, self.theory_atoms): | ||||||
|  |             init.add_watch(lit) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def truthy_atoms_text(self): | ||||||
|  |         return (str(self.lookup_solver_lit(atom)[0]) for atom in self.assignment if self.assignment[atom]) | ||||||
|  | 
 | ||||||
|  |     def atom_text_to_dl_atom(self, atoms: Iterable[str]) -> Iterable[int]: | ||||||
|  |         return map(self.theory_atoms.get, atoms) | ||||||
|  | 
 | ||||||
|  |     def falsey_atoms_text(self): | ||||||
|  |         return (str(self.lookup_solver_lit(atom)[0]) for atom in self.assignment if not self.assignment[atom]) | ||||||
|  | 
 | ||||||
|  |     def propagate(self, pcontrol: PropagateControl, changes) -> None: | ||||||
|  |         for change in changes: | ||||||
|  |             atom = abs(change) | ||||||
|  |             assert atom not in self.assignment | ||||||
|  |             self.assignment[atom] = change >= 0 | ||||||
|  |          | ||||||
|  |         in_atoms = set(self.truthy_atoms_text()) | ||||||
|  |         out_atoms = self.atom_text_to_dl_atom(O.propagate()) | ||||||
|  |         new_atoms = out_atoms - in_atoms | ||||||
|  |         new_lits = self.atom_text_to_dl_atom(new_atoms) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def undo(self, thread_id: int, assignment: Assignment, changes: List[int]): | ||||||
|  |         for change in changes: | ||||||
|  |             atom = abs(change) | ||||||
|  |             del self.assignment[atom] | ||||||
|  | 
 | ||||||
|  |     def check(self, pcontrol: PropagateControl) -> None: | ||||||
|  |         self.print_assignment() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def print_assignment(self): | ||||||
|  |         print("assignment: ", end="") | ||||||
|  |         for lit in self.assignment: | ||||||
|  |             lit = -lit if not self.assignment[lit] else lit | ||||||
|  |             print(self.solver_lit_text(lit), end=" ") | ||||||
|  |         print() | ||||||
|  | 
 | ||||||
|  |     def is_theory_atom(self, lit: int): | ||||||
|  |         _, _, a = self.lookup_solver_lit(lit) | ||||||
|  |         return a | ||||||
|  | 
 | ||||||
|  |     def solver_lit_text(self, lit: int): | ||||||
|  |         symbol, is_neg, is_theory = self.lookup_solver_lit(lit) | ||||||
|  |         if symbol is None: | ||||||
|  |             return None | ||||||
|  |         theory = "O: " if is_theory else "" | ||||||
|  |         neg = "not " if is_neg else "" | ||||||
|  |         return f"({theory}{neg}{symbol})" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     def lookup_solver_lit(self, lit: int) -> Tuple[Symbol, bool, bool]: | ||||||
|  |         atom = abs(lit) | ||||||
|  |         if (atom_symb := self.symbolic_atoms.get(atom, None)) is not None: | ||||||
|  |             return atom_symb, lit < 0, False | ||||||
|  |         if (theo_symbol := self.theory_atoms.get(atom, None)) is not None: | ||||||
|  |             return theo_symbol, lit < 0, True | ||||||
|  |         return None, False, False | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | program=""" | ||||||
|  | a :- not b. | ||||||
|  | b :- not a. | ||||||
|  | c :- not d. | ||||||
|  | """ | ||||||
|  | 
 | ||||||
|  | # Need to ground program before we can look up symbolic atoms and | ||||||
|  | # Having two waves of grounding might be having some weird effects | ||||||
|  | # So we parse and ground and then revert back to text then reparse | ||||||
|  | def add_external_atoms(program: str) -> str: | ||||||
|  |     control = clingo.Control(["0"]) | ||||||
|  |     control.add("base", [], program) | ||||||
|  |     control.ground([("base", [])]) | ||||||
|  | 
 | ||||||
|  |     theory_grammar = """ | ||||||
|  | #theory o { | ||||||
|  |     kterm {- : 0, unary }; | ||||||
|  |     &o/0 : kterm, any | ||||||
|  | }. | ||||||
|  |     """ | ||||||
|  |     external_atoms = "\n".join( | ||||||
|  |         f"{atom} :- &o{{{atom}}}." for atom in  | ||||||
|  |         (str(atom.symbol) for atom in control.symbolic_atoms) | ||||||
|  |     ) | ||||||
|  |     return theory_grammar + program + external_atoms | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | program = add_external_atoms(program) | ||||||
|  | control = clingo.Control(["0"]) | ||||||
|  | propagator = Ontology() | ||||||
|  | control.register_propagator(propagator) | ||||||
|  | control.add("base", [], program) | ||||||
|  | control.ground([("base", [])]) | ||||||
|  | 
 | ||||||
|  | # control.add("external", [], theory_grammar + external_atoms) | ||||||
|  | 
 | ||||||
|  | # control.ground([("external", [])]) | ||||||
|  | 
 | ||||||
|  | with control.solve(yield_=True) as solve_handle: | ||||||
|  |     for model in solve_handle: | ||||||
|  |         print("answer set:", model) | ||||||
|  | 
 | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue