Skip to content

Commit 35d056c

Browse files
Merge pull request #31 from dreamer-coding/main
2 parents 163567c + 2739935 commit 35d056c

File tree

1 file changed

+73
-18
lines changed

1 file changed

+73
-18
lines changed

code/logic/jellyfish.c

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,43 @@
1616
#include <stdio.h>
1717
#include <time.h>
1818

19-
// Simple placeholder hash function (not cryptographic, just consistent)
2019
void fossil_jellyfish_hash(const char *input, const char *output, uint8_t *hash_out) {
21-
// Enhanced: Use a simple FNV-1a-like mixing over input and output
2220
const uint32_t FNV_PRIME = 0x01000193;
2321
uint32_t hash = 0x811c9dc5;
2422
size_t in_len = strlen(input);
2523
size_t out_len = strlen(output);
2624

25+
// Mix in lengths
26+
hash ^= in_len;
27+
hash *= FNV_PRIME;
28+
hash ^= out_len;
29+
hash *= FNV_PRIME;
30+
2731
// Mix input
2832
for (size_t i = 0; i < in_len; ++i) {
2933
hash ^= (uint8_t)input[i];
3034
hash *= FNV_PRIME;
35+
hash ^= (hash >> 5);
3136
}
37+
3238
// Mix output
3339
for (size_t i = 0; i < out_len; ++i) {
3440
hash ^= (uint8_t)output[i];
3541
hash *= FNV_PRIME;
42+
hash ^= (hash >> 5);
3643
}
3744

38-
// Spread hash into hash_out buffer
45+
// Final mix
46+
hash ^= (hash << 7);
47+
hash ^= (hash >> 3);
48+
49+
// Spread into output
50+
uint32_t h = hash;
3951
for (size_t i = 0; i < FOSSIL_JELLYFISH_HASH_SIZE; ++i) {
40-
hash ^= (hash >> 13);
41-
hash *= FNV_PRIME;
42-
hash_out[i] = (uint8_t)((hash >> (8 * (i % 4))) & 0xFF);
52+
h ^= (h >> 13);
53+
h *= FNV_PRIME;
54+
h ^= (h << 11);
55+
hash_out[i] = (uint8_t)((h >> (8 * (i % 4))) & 0xFF);
4356
}
4457
}
4558

@@ -123,13 +136,30 @@ int fossil_jellyfish_load(fossil_jellyfish_chain *chain, const char *filepath) {
123136
return 1;
124137
}
125138

126-
// Simple Levenshtein-like distance (cost is # of mismatched chars)
127139
static int fossil_jellyfish_similarity(const char *a, const char *b) {
128-
int score = 0;
129-
for (int i = 0; a[i] && b[i]; ++i) {
130-
if (a[i] != b[i]) score++;
140+
int cost = 0;
141+
size_t i = 0, j = 0;
142+
143+
while (a[i] && b[j]) {
144+
char ac = a[i];
145+
char bc = b[j];
146+
147+
// case-insensitive match
148+
if (ac >= 'A' && ac <= 'Z') ac += 32;
149+
if (bc >= 'A' && bc <= 'Z') bc += 32;
150+
151+
if (ac != bc) {
152+
cost++;
153+
}
154+
i++;
155+
j++;
131156
}
132-
return score;
157+
158+
// Penalty for remaining characters
159+
while (a[i++]) cost++;
160+
while (b[j++]) cost++;
161+
162+
return cost;
133163
}
134164

135165
const char* fossil_jellyfish_reason_fuzzy(fossil_jellyfish_chain *chain, const char *input) {
@@ -140,31 +170,56 @@ const char* fossil_jellyfish_reason_fuzzy(fossil_jellyfish_chain *chain, const c
140170
if (!chain->memory[i].valid) continue;
141171

142172
int score = fossil_jellyfish_similarity(input, chain->memory[i].input);
173+
if (score == 0) return chain->memory[i].output; // Exact match
143174
if (score < best_score) {
144175
best_score = score;
145176
best_output = chain->memory[i].output;
146177
}
147178
}
148179

180+
// impose a fuzzy threshold
181+
if (best_score > (int)(strlen(input) / 2)) {
182+
return "Unknown";
183+
}
184+
149185
return best_output;
150186
}
151187

152188
void fossil_jellyfish_decay_confidence(fossil_jellyfish_chain *chain, float decay_rate) {
189+
const float MIN_CONFIDENCE = 0.05f;
190+
153191
for (size_t i = 0; i < chain->count; ++i) {
154192
if (!chain->memory[i].valid) continue;
155193

156-
chain->memory[i].confidence -= decay_rate;
157-
if (chain->memory[i].confidence < 0.05f) {
158-
chain->memory[i].valid = 0; // mark for cleanup
194+
// Apply exponential decay
195+
chain->memory[i].confidence *= (1.0f - decay_rate);
196+
197+
// Clamp to zero
198+
if (chain->memory[i].confidence < 0.0f) {
199+
chain->memory[i].confidence = 0.0f;
200+
}
201+
202+
// Invalidate if confidence too low
203+
if (chain->memory[i].confidence < MIN_CONFIDENCE) {
204+
chain->memory[i].valid = 0;
159205
}
160206
}
161207
}
162208

163209
const char* fossil_jellyfish_reason_chain(fossil_jellyfish_chain *chain, const char *input, int depth) {
164-
if (depth <= 0) return input;
210+
const char *current = input;
211+
const char *last_valid = input;
212+
213+
for (int i = 0; i < depth; ++i) {
214+
const char *next = fossil_jellyfish_reason_fuzzy(chain, current);
165215

166-
const char *first = fossil_jellyfish_reason_fuzzy(chain, input);
167-
if (strcmp(first, "Unknown") == 0) return first;
216+
if (strcmp(next, "Unknown") == 0 || strcmp(next, current) == 0) {
217+
break;
218+
}
219+
220+
last_valid = next;
221+
current = next;
222+
}
168223

169-
return fossil_jellyfish_reason_chain(chain, first, depth - 1);
224+
return last_valid;
170225
}

0 commit comments

Comments
 (0)