chore: progress on generative grammar

This commit is contained in:
Sara Gerretsen 2026-03-26 14:53:21 +01:00
parent 1d4feabf7e
commit eb320acbcd
2 changed files with 20 additions and 13 deletions

View file

@ -1,6 +1,7 @@
#include "generative_grammar/symbol.h"
#include "core/error/error_macros.h"
#include "core/object/class_db.h"
#include "core/templates/hash_map.h"
void Symbol::_bind_methods() {
BIND_HPROPERTY(Variant::INT, symbol, PROPERTY_HINT_ENUM, Type_hint());
@ -8,7 +9,7 @@ void Symbol::_bind_methods() {
}
bool Symbol::is_terminal() const {
switch (this->type) {
switch (this->symbol) {
default:
return false;
}
@ -39,11 +40,11 @@ TypedArray<Ref<Symbol>> Symbol::get_children_array() const {
}
void Rule::_bind_methods() {
BIND_HPROPERTY(Variant::OBJECT, match, PROPERTY_HINT_RESOURCE_TYPE, "Symbol");
BIND_HPROPERTY(Variant::OBJECT, pattern, PROPERTY_HINT_RESOURCE_TYPE, "Symbol");
BIND_HPROPERTY(Variant::OBJECT, result, PROPERTY_HINT_RESOURCE_TYPE, "Symbol");
}
bool Rule::symbols_match(Ref<Symbol> match, Ref<Symbol> pattern) {
bool Rule::match_symbols(Ref<Symbol> match, Ref<Symbol> pattern, HashMap<Ref<Symbol>, Ref<Symbol>> &matches) {
if (match == pattern) {
return true; // reference match or null match
}
@ -57,14 +58,11 @@ bool Rule::symbols_match(Ref<Symbol> match, Ref<Symbol> pattern) {
if (match->get_children().size() < pattern->get_children().size()) {
return false; // too little children to be able to match
}
if ((match->get_parent() == nullptr) != (pattern->get_parent() == nullptr)) {
return false; // mismatch in existence of incoming edge
}
// check for matching outgoing edges
for (Ref<Symbol> pattern_symbol : pattern->get_children()) {
bool match_found{ false };
for (Ref<Symbol> match_symbol : match->get_children()) {
if (symbols_match(match_symbol, pattern_symbol)) {
if (match_symbols(match_symbol, pattern_symbol, matches)) {
match_found = true;
break;
}
@ -73,8 +71,18 @@ bool Rule::symbols_match(Ref<Symbol> match, Ref<Symbol> pattern) {
return false;
}
}
matches.insert(pattern, match);
return true;
}
bool Rule::matches(Ref<Symbol> graph) {
bool Rule::try_apply(Ref<Symbol> match) {
// identify corresponding symbols
HashMap<Ref<Symbol>, Ref<Symbol>> symbols{};
if (!match_symbols(match, this->pattern, symbols)) {
return false;
}
// clear matching edges
for (KeyValue<Ref<Symbol>, Ref<Symbol>> kvp : symbols) {
}
return true;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include "core/io/resource.h"
#include "core/templates/hash_map.h"
#include "core/templates/hash_set.h"
#include "core/variant/type_info.h"
#include "core/variant/typed_array.h"
@ -32,18 +33,16 @@ MAKE_TYPE_INFO(Symbol::Type, Variant::INT);
struct Rule : public Resource {
GDCLASS(Rule, Resource);
static void _bind_methods();
bool symbols_match(Ref<Symbol> match, Ref<Symbol> pattern);
bool match_symbols(Ref<Symbol> match, Ref<Symbol> pattern, HashMap<Ref<Symbol>, Ref<Symbol>> &matches);
public:
bool matches(Ref<Symbol> graph);
void apply(Ref<Symbol> graph);
bool try_apply(Ref<Symbol> graph);
private:
Ref<Symbol> match{};
Ref<Symbol> pattern{};
Ref<Symbol> result{};
public:
GET_SET_FNS(Ref<Symbol>, match);
GET_SET_FNS(Ref<Symbol>, pattern);
GET_SET_FNS(Ref<Symbol>, result);
};