MarcdeFalco commited on
Commit
f990767
Β·
verified Β·
1 Parent(s): 01ff4e2

undefined - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +429 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Combinators
3
- emoji: 🐠
4
- colorFrom: green
5
- colorTo: blue
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: combinators
3
+ emoji: 🐳
4
+ colorFrom: red
5
+ colorTo: purple
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,429 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Combinator Logic Playground</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .combinator {
11
+ transition: all 0.2s ease;
12
+ }
13
+ .combinator.dragging {
14
+ opacity: 0.5;
15
+ transform: scale(1.1);
16
+ }
17
+ .drop-zone {
18
+ min-height: 100px;
19
+ transition: all 0.2s ease;
20
+ }
21
+ .drop-zone.highlight {
22
+ background-color: rgba(147, 197, 253, 0.3);
23
+ border-color: #3b82f6;
24
+ }
25
+ .expression-item {
26
+ position: relative;
27
+ }
28
+ .expression-item:hover .remove-btn {
29
+ opacity: 1;
30
+ }
31
+ .remove-btn {
32
+ opacity: 0;
33
+ transition: opacity 0.2s;
34
+ position: absolute;
35
+ top: -8px;
36
+ right: -8px;
37
+ width: 20px;
38
+ height: 20px;
39
+ border-radius: 50%;
40
+ background-color: #ef4444;
41
+ color: white;
42
+ display: flex;
43
+ align-items: center;
44
+ justify-content: center;
45
+ font-size: 10px;
46
+ cursor: pointer;
47
+ }
48
+ @keyframes pulse {
49
+ 0%, 100% { transform: scale(1); }
50
+ 50% { transform: scale(1.05); }
51
+ }
52
+ .reduction-step {
53
+ animation: pulse 0.5s ease;
54
+ }
55
+ </style>
56
+ </head>
57
+ <body class="bg-gray-50 min-h-screen">
58
+ <div class="container mx-auto px-4 py-8">
59
+ <header class="mb-8 text-center">
60
+ <h1 class="text-3xl font-bold text-blue-600 mb-2">Combinator Logic Playground</h1>
61
+ <p class="text-gray-600">Drag and drop combinators to form expressions and reduce them</p>
62
+ </header>
63
+
64
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
65
+ <!-- Combinator Palette -->
66
+ <div class="bg-white rounded-lg shadow-md p-4">
67
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
68
+ <i class="fas fa-shapes mr-2 text-blue-500"></i> Combinators
69
+ </h2>
70
+ <div class="grid grid-cols-2 gap-3">
71
+ <div class="combinator bg-blue-100 text-blue-800 py-3 px-4 rounded-lg cursor-move flex items-center justify-center font-mono font-bold"
72
+ draggable="true" data-type="S">
73
+ <span>S</span>
74
+ </div>
75
+ <div class="combinator bg-green-100 text-green-800 py-3 px-4 rounded-lg cursor-move flex items-center justify-center font-mono font-bold"
76
+ draggable="true" data-type="K">
77
+ <span>K</span>
78
+ </div>
79
+ <div class="combinator bg-purple-100 text-purple-800 py-3 px-4 rounded-lg cursor-move flex items-center justify-center font-mono font-bold"
80
+ draggable="true" data-type="I">
81
+ <span>I</span>
82
+ </div>
83
+ <div class="combinator bg-yellow-100 text-yellow-800 py-3 px-4 rounded-lg cursor-move flex items-center justify-center font-mono font-bold"
84
+ draggable="true" data-type="B">
85
+ <span>B</span>
86
+ </div>
87
+ <div class="combinator bg-red-100 text-red-800 py-3 px-4 rounded-lg cursor-move flex items-center justify-center font-mono font-bold"
88
+ draggable="true" data-type="C">
89
+ <span>C</span>
90
+ </div>
91
+ <div class="combinator bg-indigo-100 text-indigo-800 py-3 px-4 rounded-lg cursor-move flex items-center justify-center font-mono font-bold"
92
+ draggable="true" data-type="W">
93
+ <span>W</span>
94
+ </div>
95
+ </div>
96
+ <div class="mt-4">
97
+ <div class="combinator bg-gray-200 text-gray-800 py-2 px-3 rounded-lg cursor-move flex items-center justify-center font-mono text-sm"
98
+ draggable="true" data-type="variable">
99
+ <span>Variable (drag to edit)</span>
100
+ </div>
101
+ </div>
102
+ </div>
103
+
104
+ <!-- Workspace -->
105
+ <div class="bg-white rounded-lg shadow-md p-4">
106
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
107
+ <i class="fas fa-edit mr-2 text-blue-500"></i> Workspace
108
+ </h2>
109
+ <div id="expression-container" class="drop-zone border-2 border-dashed border-gray-300 rounded-lg p-4 mb-4 min-h-32">
110
+ <p class="text-gray-400 text-center py-8" id="empty-message">Drag combinators here to build your expression</p>
111
+ <div class="flex flex-wrap gap-2" id="expression-items"></div>
112
+ </div>
113
+ <div class="flex flex-wrap gap-2">
114
+ <button id="reduce-btn" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center disabled:opacity-50" disabled>
115
+ <i class="fas fa-play mr-2"></i> Reduce
116
+ </button>
117
+ <button id="reset-btn" class="bg-gray-500 hover:bg-gray-600 text-white px-4 py-2 rounded-lg flex items-center">
118
+ <i class="fas fa-redo mr-2"></i> Reset
119
+ </button>
120
+ <button id="add-parens-btn" class="bg-purple-500 hover:bg-purple-600 text-white px-4 py-2 rounded-lg flex items-center">
121
+ <i class="fas fa-parentheses mr-2"></i> Add Parentheses
122
+ </button>
123
+ </div>
124
+ </div>
125
+
126
+ <!-- Reduction Steps -->
127
+ <div class="bg-white rounded-lg shadow-md p-4">
128
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
129
+ <i class="fas fa-list-ol mr-2 text-blue-500"></i> Reduction Steps
130
+ </h2>
131
+ <div id="reduction-steps" class="space-y-2 max-h-96 overflow-y-auto p-2">
132
+ <p class="text-gray-400 text-center py-8">Your reduction steps will appear here</p>
133
+ </div>
134
+ </div>
135
+ </div>
136
+
137
+ <!-- Help Section -->
138
+ <div class="mt-8 bg-white rounded-lg shadow-md p-4">
139
+ <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
140
+ <i class="fas fa-question-circle mr-2 text-blue-500"></i> Combinator Definitions
141
+ </h2>
142
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
143
+ <div class="bg-blue-50 p-3 rounded-lg">
144
+ <h3 class="font-mono font-bold text-blue-800">S x y z = x z (y z)</h3>
145
+ <p class="text-gray-600 text-sm">Substitution combinator</p>
146
+ </div>
147
+ <div class="bg-green-50 p-3 rounded-lg">
148
+ <h3 class="font-mono font-bold text-green-800">K x y = x</h3>
149
+ <p class="text-gray-600 text-sm">Constant combinator</p>
150
+ </div>
151
+ <div class="bg-purple-50 p-3 rounded-lg">
152
+ <h3 class="font-mono font-bold text-purple-800">I x = x</h3>
153
+ <p class="text-gray-600 text-sm">Identity combinator</p>
154
+ </div>
155
+ <div class="bg-yellow-50 p-3 rounded-lg">
156
+ <h3 class="font-mono font-bold text-yellow-800">B x y z = x (y z)</h3>
157
+ <p class="text-gray-600 text-sm">Composition combinator</p>
158
+ </div>
159
+ <div class="bg-red-50 p-3 rounded-lg">
160
+ <h3 class="font-mono font-bold text-red-800">C x y z = x z y</h3>
161
+ <p class="text-gray-600 text-sm">Swap combinator</p>
162
+ </div>
163
+ <div class="bg-indigo-50 p-3 rounded-lg">
164
+ <h3 class="font-mono font-bold text-indigo-800">W x y = x y y</h3>
165
+ <p class="text-gray-600 text-sm">Duplication combinator</p>
166
+ </div>
167
+ </div>
168
+ </div>
169
+ </div>
170
+
171
+ <script>
172
+ document.addEventListener('DOMContentLoaded', function() {
173
+ // DOM elements
174
+ const expressionContainer = document.getElementById('expression-container');
175
+ const expressionItems = document.getElementById('expression-items');
176
+ const emptyMessage = document.getElementById('empty-message');
177
+ const reduceBtn = document.getElementById('reduce-btn');
178
+ const resetBtn = document.getElementById('reset-btn');
179
+ const addParensBtn = document.getElementById('add-parens-btn');
180
+ const reductionSteps = document.getElementById('reduction-steps');
181
+
182
+ // Store the current expression and reduction steps
183
+ let currentExpression = [];
184
+ let steps = [];
185
+
186
+ // Add drag events to all combinators
187
+ document.querySelectorAll('.combinator').forEach(combinator => {
188
+ combinator.addEventListener('dragstart', dragStart);
189
+ });
190
+
191
+ // Setup drop zones
192
+ expressionContainer.addEventListener('dragover', dragOver);
193
+ expressionContainer.addEventListener('dragleave', dragLeave);
194
+ expressionContainer.addEventListener('drop', drop);
195
+
196
+ // Button events
197
+ reduceBtn.addEventListener('click', reduceExpression);
198
+ resetBtn.addEventListener('click', resetWorkspace);
199
+ addParensBtn.addEventListener('click', addParentheses);
200
+
201
+ // Drag start handler
202
+ function dragStart(e) {
203
+ this.classList.add('dragging');
204
+ e.dataTransfer.setData('text/plain', this.dataset.type);
205
+ e.dataTransfer.effectAllowed = 'move';
206
+ }
207
+
208
+ // Drag over handler
209
+ function dragOver(e) {
210
+ e.preventDefault();
211
+ this.classList.add('highlight');
212
+ e.dataTransfer.dropEffect = 'move';
213
+ }
214
+
215
+ // Drag leave handler
216
+ function dragLeave() {
217
+ this.classList.remove('highlight');
218
+ }
219
+
220
+ // Drop handler
221
+ function drop(e) {
222
+ e.preventDefault();
223
+ this.classList.remove('highlight');
224
+
225
+ const combinatorType = e.dataTransfer.getData('text/plain');
226
+ addCombinatorToExpression(combinatorType);
227
+ }
228
+
229
+ // Add combinator to expression
230
+ function addCombinatorToExpression(type, isParens = false) {
231
+ // Hide empty message if this is the first item
232
+ if (currentExpression.length === 0) {
233
+ emptyMessage.style.display = 'none';
234
+ reduceBtn.disabled = false;
235
+ }
236
+
237
+ // Create a unique ID for this combinator
238
+ const id = Date.now().toString(36) + Math.random().toString(36).substr(2);
239
+
240
+ // Add to current expression
241
+ currentExpression.push({
242
+ id,
243
+ type,
244
+ isParens
245
+ });
246
+
247
+ // Update the UI
248
+ updateExpressionUI();
249
+ }
250
+
251
+ // Update the expression UI
252
+ function updateExpressionUI() {
253
+ expressionItems.innerHTML = '';
254
+
255
+ currentExpression.forEach((item, index) => {
256
+ const itemEl = document.createElement('div');
257
+ itemEl.className = 'expression-item';
258
+ itemEl.dataset.id = item.id;
259
+
260
+ let bgColor, textColor;
261
+
262
+ if (item.isParens) {
263
+ itemEl.className += ' cursor-default';
264
+ itemEl.innerHTML = '(';
265
+ } else {
266
+ itemEl.className += ' cursor-move';
267
+ itemEl.draggable = true;
268
+ itemEl.addEventListener('dragstart', dragStart);
269
+
270
+ switch(item.type) {
271
+ case 'S':
272
+ bgColor = 'bg-blue-100';
273
+ textColor = 'text-blue-800';
274
+ break;
275
+ case 'K':
276
+ bgColor = 'bg-green-100';
277
+ textColor = 'text-green-800';
278
+ break;
279
+ case 'I':
280
+ bgColor = 'bg-purple-100';
281
+ textColor = 'text-purple-800';
282
+ break;
283
+ case 'B':
284
+ bgColor = 'bg-yellow-100';
285
+ textColor = 'text-yellow-800';
286
+ break;
287
+ case 'C':
288
+ bgColor = 'bg-red-100';
289
+ textColor = 'text-red-800';
290
+ break;
291
+ case 'W':
292
+ bgColor = 'bg-indigo-100';
293
+ textColor = 'text-indigo-800';
294
+ break;
295
+ case 'variable':
296
+ bgColor = 'bg-gray-200';
297
+ textColor = 'text-gray-800';
298
+ break;
299
+ }
300
+
301
+ itemEl.className += ` ${bgColor} ${textColor} py-2 px-3 rounded-lg font-mono font-bold`;
302
+ itemEl.textContent = item.type === 'variable' ? 'x' : item.type;
303
+
304
+ // Add remove button
305
+ const removeBtn = document.createElement('span');
306
+ removeBtn.className = 'remove-btn';
307
+ removeBtn.innerHTML = '<i class="fas fa-times"></i>';
308
+ removeBtn.addEventListener('click', (e) => {
309
+ e.stopPropagation();
310
+ removeCombinator(item.id);
311
+ });
312
+ itemEl.appendChild(removeBtn);
313
+ }
314
+
315
+ expressionItems.appendChild(itemEl);
316
+ });
317
+ }
318
+
319
+ // Remove combinator from expression
320
+ function removeCombinator(id) {
321
+ currentExpression = currentExpression.filter(item => item.id !== id);
322
+
323
+ if (currentExpression.length === 0) {
324
+ emptyMessage.style.display = 'block';
325
+ reduceBtn.disabled = true;
326
+ }
327
+
328
+ updateExpressionUI();
329
+ }
330
+
331
+ // Add parentheses to expression
332
+ function addParentheses() {
333
+ if (currentExpression.length === 0) return;
334
+
335
+ // Add opening parenthesis
336
+ addCombinatorToExpression('(', true);
337
+
338
+ // Add closing parenthesis at the end
339
+ setTimeout(() => {
340
+ addCombinatorToExpression(')', true);
341
+ }, 0);
342
+ }
343
+
344
+ // Reset workspace
345
+ function resetWorkspace() {
346
+ currentExpression = [];
347
+ steps = [];
348
+ reductionSteps.innerHTML = '<p class="text-gray-400 text-center py-8">Your reduction steps will appear here</p>';
349
+ emptyMessage.style.display = 'block';
350
+ reduceBtn.disabled = true;
351
+ updateExpressionUI();
352
+ }
353
+
354
+ // Reduce expression
355
+ function reduceExpression() {
356
+ if (currentExpression.length === 0) return;
357
+
358
+ // Clear previous steps
359
+ steps = [];
360
+ reductionSteps.innerHTML = '';
361
+
362
+ // Get the current expression as a string
363
+ let expr = currentExpression.map(item => {
364
+ if (item.isParens) {
365
+ return item.type === '(' ? '(' : ')';
366
+ }
367
+ return item.type === 'variable' ? 'x' : item.type;
368
+ }).join(' ');
369
+
370
+ // Add initial expression to steps
371
+ addReductionStep(expr, 'Initial expression');
372
+
373
+ // Simple reduction logic (this is a simplified version)
374
+ // In a real implementation, you'd need a proper reduction algorithm
375
+ let reduced = false;
376
+
377
+ // Try to find reducible expressions
378
+ for (let i = 0; i < expr.length - 2; i++) {
379
+ const subExpr = expr.substr(i, 3);
380
+
381
+ // Check for K combinator pattern: K x y β†’ x
382
+ if (subExpr.startsWith('K ') && expr[i+2] !== ' ' && expr[i+3] !== ' ') {
383
+ const before = expr.substring(0, i);
384
+ const after = expr.substring(i + 4);
385
+ expr = before + expr[i+2] + after;
386
+ addReductionStep(expr, 'Applied K combinator: K x y β†’ x');
387
+ reduced = true;
388
+ break;
389
+ }
390
+
391
+ // Check for I combinator pattern: I x β†’ x
392
+ if (subExpr.startsWith('I ') && expr[i+2] !== ' ') {
393
+ const before = expr.substring(0, i);
394
+ const after = expr.substring(i + 3);
395
+ expr = before + expr[i+2] + after;
396
+ addReductionStep(expr, 'Applied I combinator: I x β†’ x');
397
+ reduced = true;
398
+ break;
399
+ }
400
+ }
401
+
402
+ if (!reduced) {
403
+ addReductionStep(expr, 'No further reductions possible', true);
404
+ }
405
+ }
406
+
407
+ // Add a reduction step to the UI
408
+ function addReductionStep(expression, explanation, isFinal = false) {
409
+ const stepEl = document.createElement('div');
410
+ stepEl.className = `bg-gray-50 p-3 rounded-lg mb-2 reduction-step ${isFinal ? 'border-l-4 border-blue-500' : ''}`;
411
+
412
+ const exprEl = document.createElement('div');
413
+ exprEl.className = 'font-mono text-lg mb-1';
414
+ exprEl.textContent = expression;
415
+
416
+ const explanationEl = document.createElement('div');
417
+ explanationEl.className = 'text-sm text-gray-600';
418
+ explanationEl.textContent = explanation;
419
+
420
+ stepEl.appendChild(exprEl);
421
+ stepEl.appendChild(explanationEl);
422
+
423
+ reductionSteps.appendChild(stepEl);
424
+ stepEl.scrollIntoView({ behavior: 'smooth' });
425
+ }
426
+ });
427
+ </script>
428
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=MarcdeFalco/combinators" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
429
+ </html>