Skip to content

Commit

Permalink
finally all tests pass again
Browse files Browse the repository at this point in the history
  • Loading branch information
iislucas committed Aug 22, 2024
1 parent d649d16 commit a356405
Show file tree
Hide file tree
Showing 9 changed files with 177 additions and 163 deletions.
46 changes: 23 additions & 23 deletions animated-transformer/src/lib/logic/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
### Generative Logic

```ts
const exampleRelations = ["is", "jumps-over", "runs-away", "squishes"];
const exampleRelations = ["is", "jumpsOver", "runsAway", "squishes"];
type ExampleRelations = (typeof exampleRelations)[number];

// TODO: can we skip individual instances, e.g. c0, c1, etc, and just have the kinds?
Expand Down Expand Up @@ -40,24 +40,24 @@ type ExampleObjects = (typeof exampleObjects)[number];

const relArgs = new Map<ExampleRelations, ExampleObjects[]>([
["is", ["", ""]],
["jumps-over", ["animal", ""]],
["runs-away", ["animal"]],
["jumpsOver", ["animal", ""]],
["runsAway", ["animal"]],
["squishes", ["animal", ""]],
]);

const imaginaryStory = "jumps-over _x:monkey _y, jumps-over _y _x";
const imaginaryStory = "jumpsOver _x:monkey _y, jumpsOver _y _x";

[
// Observe absolute probability rules can be inherrently inconsistent... (not sum to 1)
"P(squishes ?x ?y | jumps-over ?x:monkey ?y:flower) = 0.5",
"P(squishes ?x ?y | jumps-over ?x:animal ?y:flower) = 0.1",
"P(squishes ?x ?y | jumpsOver ?x:monkey ?y:flower) = 0.5",
"P(squishes ?x ?y | jumpsOver ?x:animal ?y:flower) = 0.1",

// Score rules instead of probability ones can work...
"S(squishes ?x ?y | jumps-over ?x:monkey ?y:flower) += 0.5", // r1
"S(squishes ?x ?y | jumps-over ?x:animal ?y:flower) += 0.1", // r2
"S(squishes ?x ?y | jumpsOver ?x:monkey ?y:flower) += 0.5", // r1
"S(squishes ?x ?y | jumpsOver ?x:animal ?y:flower) += 0.1", // r2

// Story:
"jumps-over _a:monkey _f:flower, jumps-over _c:cat _f:flower",
"jumpsOver _a:monkey _f:flower, jumpsOver _c:cat _f:flower",

// All application of score rules happen, and common matched rules then
// get aggregated.
Expand All @@ -72,40 +72,40 @@ const imaginaryStory = "jumps-over _x:monkey _y, jumps-over _y _x";

const rules = [
// Monkeys jump over stuff a lot
"S(jumps-over ?x:monkey ?y) += 5",
"S(jumpsOver ?x:monkey ?y) += 5",
// Monkeys might squish flowers
"S(squishes ?x ?y | jumps-over ?x:monkey ?y:flower) += 1",
"S(squishes ?x ?y | jumpsOver ?x:monkey ?y:flower) += 1",
// Monkeys might squish cats
"S(squishes ?x ?y | jumps-over ?x:monkey ?y:cat) += 0.5",
"S(squishes ?x ?y | jumpsOver ?x:monkey ?y:cat) += 0.5",
// cats jump over stuff
"S(jumps-over ?x:cat ?y) += 1",
"S(jumpsOver ?x:cat ?y) += 1",
// cats very occationally squish flowers
"S(squishes ?x ?y | jumps-over ?x:cat ?y:flower) += 0.1",
"S(squishes ?x ?y | jumpsOver ?x:cat ?y:flower) += 0.1",
// Elephants occationally jump over animals
"S(jumps-over ?x:elephant ?y:animal) += 0.1",
"S(jumpsOver ?x:elephant ?y:animal) += 0.1",
// Cats sometimes run away when jumped over
"S(runs-away ?y += 1 | jumps-over ?x ?y:cat)",
"S(runsAway ?y += 1 | jumpsOver ?x ?y:cat)",
// Squished animals can't run away anymore
"S(runs-away ?y | squishes ?x ?y:animal) *= 0",
"S(runsAway ?y | squishes ?x ?y:animal) *= 0",
// Animals that can away can't get squished or be jumped over.
"S(squishes ?x ?y | runs-away ?y:animal) *= 0",
"S(jumps-over ?x ?y | runs-away ?y:animal) *= 0",
"S(squishes ?x ?y | runsAway ?y:animal) *= 0",
"S(jumpsOver ?x ?y | runsAway ?y:animal) *= 0",
];

// Ideas for fancier rules/variants
//
// If a monkey just jumped over something, they are not so likely to jump again right away.
// '[... jumps-over _x _y ...:3] ==> jumps-over _x _y *= 0.1',
// '[... jumpsOver _x _y ...:3] ==> jumpsOver _x _y *= 0.1',
//
// Let actions/observations have names too.
// '_e: (tries_to_jumps_over _x:monkey _y) ==> succeeds(_e) += 1',
//
// Should types be observations?, e.g. could we write:
// '_x:cat ==> runs-away _x += 1'
// i.e. that would be the same as: 'is _x cat ==> runs-away _x += 1'
// '_x:cat ==> runsAway _x += 1'
// i.e. that would be the same as: 'is _x cat ==> runsAway _x += 1'
//
// Should we allow an unbound syntax?
// 'jumps-over monkey _y += 5' === 'jumps-over _x:monkey _y += 5' ?
// 'jumpsOver monkey _y += 5' === 'jumpsOver _x:monkey _y += 5' ?
// Maybe this is just syntax, so we skip it? Or maybe this somehow says that one
// *cannot* bind to the monkey, i.e. is says there was an unknown monkey who jumped over _y?
```
18 changes: 18 additions & 0 deletions animated-transformer/src/lib/logic/relations.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ limitations under the License.
==============================================================================*/
import {
extendTypesWithDecendent,
flattenType,
initTypeDef,
parseRel,
stringifyMapToSet,
Expand Down Expand Up @@ -52,6 +53,11 @@ describe('relations', () => {
expect(stringifyRelation(rel)).toEqual('squishes _x _y:animal _z:a|b|c');
});

it('stringifyRel: skips universal type', () => {
const rel = parseRel('is _x:*');
expect(stringifyRelation(rel)).toEqual('is _x');
});

it('initTypeDef: empty', () => {
const types = initTypeDef({});
expect(types.decendent.size).toEqual(1);
Expand All @@ -74,6 +80,18 @@ describe('relations', () => {
expect(decendent.get('animal')).toEqual(new Set(['cat', 'monkey', 'elephant']));
});

it('flattenType', () => {
const types = initTypeDef({
animal: ['cat', 'monkey', 'elephant'],
inanimate: ['rock', 'tree', 'flower'],
squishable: ['cat', 'monkey', 'flower'],
});
expect(flattenType(types, universalType).size).toBe(6);
expect(flattenType(types, 'animal').size).toBe(3);
expect(flattenType(types, 'cat').size).toBe(1);
expect(flattenType(types, 'animal')).toEqual(new Set(['cat', 'monkey', 'elephant']));
});

it('extendTypesWithDecendent', () => {
const types = initTypeDef({});
const current = {
Expand Down
14 changes: 6 additions & 8 deletions animated-transformer/src/lib/logic/relations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Type } from '@angular/core';
import { filterSet } from '../seqtasks/util';

export type TypeHierarchySpec = string[] | { [name: string]: TypeHierarchySpec };

Expand Down Expand Up @@ -162,13 +163,16 @@ export type Relation<TypeName, VarName, RelName> = {
// Flatten a set of types into the most ground types possible.
export function flattenType<TypeName>(
typeDef: TypeDef<TypeName>,
typeName: TypeName
typeName: TypeName,
onlyLeaves = true
): Set<TypeName> {
const decendents = typeDef.decendent.get(typeName)!;
if (decendents.size === 0) {
return new Set([typeName]);
} else {
return decendents;
return onlyLeaves
? filterSet((name) => typeDef.decendent.get(name)!.size === 0, decendents)
: decendents;
}
}

Expand Down Expand Up @@ -283,14 +287,8 @@ export function typeSetIsSubsetOf<TypeName>(
subTypes: Set<TypeName>,
superTypes: Set<TypeName>
): boolean {
console.log('--');
console.log('decendentMap', decendentMap);
console.log('subTypes', subTypes);
console.log('superTypes', superTypes);
const flatTys1 = flattenTypeset(decendentMap, subTypes);
console.log('flatTys1', flatTys1);
const flatTys2 = flattenTypeset(decendentMap, superTypes);
console.log('flatTys2', flatTys2);
return flatTys1.difference(flatTys2).size === 0;
}

Expand Down
Loading

0 comments on commit a356405

Please sign in to comment.